• 締切済み

CFileのReadでの例外エラー#38が発生

お世話になります。 Visual Studio2005にてC++のプログラムを作成しており、プログラム内で作成したcsvファイルをプログラム起動時に読み込むような動作を行っております。 そこで、件名のとおりの症状が発生しております。 具体的な症状としましては、csvファイルをCFileのメンバ関数Read()で読み出しているのですが、ファイル内の特定の箇所を読み出そうとしたときに、例外エラーが発生し、エラー番号を確認したところCFileException::m_IOsErrorが”38”となっていました。 ネットで調べたところ、エラー番号38はEOFエラーらしいのですが、普通EOFが見つかったのであればCFile::Read()の場合例外エラーは発生しないかと思います。また、msdnで調べたところファイルを非同期で読み込んだ場合には発生するような事が記載されておりましたが、CFile::Open時に非同期指定にはしておらずデフォルトの指定でファイルを開いております。 また、件のcsvファイルをOS上でコピー&ペーストをしようとすると、「エラー番号38により、データがコピーができない」といった警告文が表示され、コピーすることも出来ません。 このcsvファイルが破損した為なのかな?とは思っているのですが、そのはっきりした原因がわからずどうしたものかとはまっております。 もし同じ症状にあわれた方、対処方法をご存じの方がいらっしゃいましたら、情報を提供頂ければと思っております。 よろしくお願い致します。 開発環境) Windows CE 6.0 Visual Studio 2005

みんなの回答

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.3

ということで…ちょっと試してみました。 VS2005で「MFC スマート デバイス アプリケーション」でソリューションを作成。 ダイアログスタイルにして、後は標準のまま。 # 対象はWindows Mobile 6 Professionalで。 ダイアログにボタンを2つ作ってそれぞれ下記のように。(インデントは全角スペースに換えてあります) void Cqa7620250_wm60Dlg::OnBnClickedButton1() {  CFile CsvFile;  char ReadBuff[64];  BOOL fResult;  fResult = CsvFile.Open(_T("\\My Documents\\csvtest1.csv"), CFile::modeNoTruncate | CFile::modeRead | CFile::shareDenyNone);  if(fResult) {   UINT ReadSize;   do {    FillMemory(ReadBuff, sizeof(ReadBuff), 0x00);    ReadSize = CsvFile.Read(ReadBuff, 40);   } while(ReadSize != 0);   CsvFile.Close();  } } void Cqa7620250_wm60Dlg::OnBnClickedButton2() {  CFile CsvFile;  char ReadBuff[64];  BOOL fResult;  fResult = CsvFile.Open(_T("\\My Documents\\csvtest2.csv"), CFile::modeNoTruncate | CFile::modeRead | CFile::shareDenyNone);  if(fResult) {   UINT ReadSize;   do {    FillMemory(ReadBuff, sizeof(ReadBuff), 0x00);    ReadSize = CsvFile.Read(ReadBuff, 40);   } while(ReadSize != 0);   CsvFile.Close();  } } デバイスのマイドキュメント下にそれぞれファイルを作成して、 1行40バイト(38文字+改行コード)のASCIIファイルを。 3行で、csvtest1.csvは最終行にも改行を置いて、csvtest2.csvは最終行の改行はナシ。 } while(ReadSize != 0); の行にブレークポイントを置いて実行。 どちらも例外は吐きませんでした。 # 最終行読み込んだ後はReadSizeが0になって返却されてループを抜けます。 う~~ん…何が問題なんですかねぇ……。 Microsoft Visual Studio 8\VC\ce\atlmfc\src\mfc\filecore.cppの  if (!::ReadFile(m_hFile, lpBuf, nCount, &dwRead, NULL))   CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName); ってどういう状態の時に動くのやら……。

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.2

>エラーのあった行が最終行のデータだった為、エラーのあった行の直後の行の読み出し確認にはCFile::Seek()を使用し、エラー行分(40B)シークしてデータの読み出しをしました。 最終行で改行があるか…とか問題になり……ますかね? # 改行がなくて40バイトに満たない。とか…… もっともそれでも例外にはならないハズですが。 >エラー番号の38ですが、CFileException::mIOsErrorが38ということでGetLastError()の返りが38だと確認したわけではありません。 CE版のMFCのソースだと…GetLastError()の値をCFileExceptionでthrowしている感じ…ですけど……。 >この例外エラーが発生した状態でGetLastError()を読み出したところ、GetLastError()でのエラーが発生してしまい呼び出すことが出来ませんでした。 というのも変な状態ですね……。 # 間のどこかで別にSetLastError()された…とか??? >その位置がEOFだと考えその位置からさらにデータを読み出したところ特に例外が発生せず、読み出したデータ数が0となるだけだったので、例外が発生しないと記述致しました。 CFile::Read()の戻り値が0…ということになるんでしょうかね。 MFCは使っていないので、ソースを読んだ程度なのですが。 # CE版はさらにサブセットになりますしね……。 >CE 6.0のヘルプも調べたところ 5.9とか書いてしまいましたが5.0の間違いでした。 VS2005のMSDN ライブラリで検索すると…CE 5.0の方しか出てこないんですよね…… WM 6.5のSDK入っているのに…… # VS2005でWM6.5のプロジェクトからヘルプ呼べば出るかなぁ。 >PCでは0x1AがEOFと判断していたのに対し、CE機では0x1Aはそのままの数字としてよみこむことが出来ました。 0x1AがEOFになるのは……テキストモードで開いた場合ですよね? CFileだと0x1AはEOF判定しなかったと思いますが。 CStdioFileでテキストモード指定した場合…かと思われますが、その辺りはどうなんでしょう…。 # 自宅帰らないとMFCのソースは確認できないです。 WindowsAPIのCreateFile()でファイルを扱っている場合、テキストモードとバイナリモードの区別はないハズなので…EOFの判定はファイルを最後まで読んだかどうか…くらいかと。 状態がいまいち不明…ですね。 手元のWM機だと…Hybrid W-ZERO3しかない…のですが……。 # リコリスがデータをcsvで持っていますが…1行のサイズが不定なんですよねぇ……。 # まぁ、1行40バイトの適当なcsvファイル作って試せばいいのでしょうけど。 # 仕事が忙しいので試せるかは別問題ですが。(今夜ならちょっと時間取れそうかな…)

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

ファイルの特定の場所…ということならば、その周辺はどんなデータになっているんでしょう? WindowsMobile6の(というかVS2005の?)MFCのCFile::Read()見る限りだと、 APIのReadFile()で読み込みに失敗した…というときのようですが……。 # で、そのときのGetLastError()が0x00000038…ということかと。 >普通EOFが見つかったのであればCFile::Read()の場合例外エラーは発生しないかと思います。 EOFの状態でCFile::Read()すると…例外になるかと思われますが。 ReadFile()APIが失敗しますので。 >また、msdnで調べたところファイルを非同期で読み込んだ場合には発生するような事が記載されておりましたが、CFile::Open時に非同期指定にはしておらずデフォルトの指定でファイルを開いております。 WindowsMobileでは非同期読み込みは非サポート…かと。 少なくともヘルプで参照できるCE5.9のドキュメントでは >lpOverlapped >[in] Unsupported; set to NULL. です。

tmk_0319
質問者

お礼

ご回答頂きましてありがとうございます。 >ファイルの特定の場所…ということならば、その周辺はどんなデータになっているんでしょう? 今回作成しているcsvファイルは1行あたり40バイトの列のデータとなっており、読み込みエラーが発生する行以外の直前、直後の行は問題なくデータを読み出すことが出来ました。エラーのあった行が最終行のデータだった為、エラーのあった行の直後の行の読み出し確認にはCFile::Seek()を使用し、エラー行分(40B)シークしてデータの読み出しをしました。 ># で、そのときのGetLastError()が0x00000038…ということかと。 エラー番号の38ですが、CFileException::mIOsErrorが38ということでGetLastError()の返りが38だと確認したわけではありません。というのも、この例外エラーが発生した状態でGetLastError()を読み出したところ、GetLastError()でのエラーが発生してしまい呼び出すことが出来ませんでした。 >EOFの状態でCFile::Read()すると…例外になるかと思われますが。 >ReadFile()APIが失敗しますので。 PC、CE組み込み機どちらでもEOFまでCFile::Read()を読み出したところ、EOFまで読み出した場合には引数の読み出したいデータ数と、返り値の読み出したデータ数が異なるようになり、その位置がEOFだと考えその位置からさらにデータを読み出したところ特に例外が発生せず、読み出したデータ数が0となるだけだったので、例外が発生しないと記述致しました。 >WindowsMobileでは非同期読み込みは非サポート…かと。 CE 6.0のヘルプも調べたところ、同じく非同期読み込みは対応していないとのことでした。申し訳ございませんでした。 PCとCE機で同じサンプルファイルを読み込んでテストしたところ、PCでは0x1AがEOFと判断していたのに対し、CE機では0x1Aはそのままの数字としてよみこむことが出来ました。CEでのEOFコードというのはどのような値なのでしょうね。。

関連するQ&A

  • CFileのOpenで例外(998:メモリ ロケーションへのアクセスが無効)

    【環境】WindowsXP、VS2005++、MFC タイトルの通りなんですが、CFileのOpen時に例外が発生してしまいます。 CFile file; LPCSTR output; file.Open(output, CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite); 関数Aに記載しており、何度かその関数を呼ぶと、決まったタイミングで例外が発生します。 GetLastErrorで998が返ってきている事は分かったのですが、 どう解決すれば良いのかわかりません・・・。 ちなみにopenしているのはBMPファイルです。 以上、ご教授お願いいたしますm(__)m

  • C#で例外が発生したとき、例外をthrowした場所を知りたい。

    Visual Studio 2005(C# 2.0 )を使っています。 例外が発生したとき、例外をthrowした場所を知りたいのですが、可能でしょうか。可能であればどうすればよいのでしょうか。

  • リリース版にすると例外エラーが発生する

    同じような質問がないか検索したのですが、ないようなので質問させてもらいます。 Visual C++2010 Expressを使ってプログラムを書いている、アプリケーション作成初心者です。 デバッグが一区切りしたため、リリース版でビルドし実行したところ、コンストラクターの 内部で、下記のエラーが発生しました。 ”アプリケーションのコンポーネントで、ハンドルされていない例外が発生しました。” ”使用されたパラメータが有効ではありません” デバッグ版では、発生しません。 エラーが発生するコードは、以下の行です。 InitializeComponent(); Blank = gcnew Bitmap("Blank.png"); この、Bitmapをgcnewする行で、上記のエラーウィンドウが表示されます。 ビルドパラメータは、リンカ入力の追加の依存ファイルに"Wsock32.lib"が指定されています。 他は、変更していません。 メモリの問題でしょうか? よろしくお願い致します。

  • 例外エラー時、例外発生箇所を取得するには

    XP、VB6.0で開発しております。 例外エラー時の処理について、教えて頂けますでしょうか。 予期せぬエラーが発生した時のため、エラーハンドルを設けて 相応の処理を実行しようと思うのですが 例外が発生したファイル名、関数名、ファイル行番号を取得するには どうすれば宜しいのでしょうか。 Cの__FILE__、__func__、__LINE__マクロに変わるような関数 もしくは方法をご存知の方、いらっしゃいましたらご教示願います。 今は以下のような処理を施しています。 (関数毎に、エラーハンドルを設け、範囲を絞り込む) 最悪、これで進めようと思うのですが、行番号が取れないので どこでエラーが発生したのか、正確に把握する事が出来ません。 TEST.frm ---------------------------------- Dim Const FILE_NAME As String = "TEST.frm" Private Sub TestFunction On Error Goto TestFunction_ErrHandle (省略) Exit Sub TestFunction_ErrHandle: ErrFunction(FILE_NAME, "TestFunction") 宜しくお願い致します。

  • C++の例外

    VS2005でtest.exe から test.dll(VC++)を呼んで、プログラムを作っています。 しかし、デバッグの時に、以下の例外が発生しました。 test.exe の 0x7c812a5b で初回の例外が発生しました: Microsoft C++ の例外: int (メモリの場所 0x00115820)。 以上の例外は、どういう意味でしょうか? メモリのアクセスのエラーでしょうか? test.dllプログラムの構造としては、以下のようになります。 char readrecordTemp[READ_SIZE + 1]; memset(readrecordTemp,0x00,sizeof(readrecordTemp)); char returncode1 = 0; char returncode2 = 0; try{ for(;;){ if (NULL == fgets(readrecordTemp,VT_MAX_READ_SIZE, m_fp)){ if (ferror(m_fp)){ throw ERROR_IO; } if (feof(m_fp)){ throw EOF; } } returncode1 =readrecordTemp[strlen(readrecordTemp) -2 ]; returncode2 =readrecordTemp[strlen(readrecordTemp) -1 ]; 。。。。 。。。。 } ファイルの最後になったら、自分が定義した例外で returncode1 =readrecordTemp[strlen(readrecordTemp) -2 ]; returncode2 =readrecordTemp[strlen(readrecordTemp) -1 ]; などを飛ばしたいですが、デバッグの時に、 returncode1 =readrecordTemp[strlen(readrecordTemp) -2 ];のところで 以上の例外が出されました。どうすればいいですか?

  • 【COBOL】read文でエラー

    COBOLで以下のエラーが発生しています。 ↓ xxファイルの'READ'文で,実行順序の誤りが発生しました.'AT-END '. PGM=xx. LINE=xxx PGの内容としては、 2つのinputファイルを読み込み、マッチング処理を行ってoutputするという処理です。 エラー行数は、2つ目のinputファイルをreadするところでエラーとなっています。 2つの異なったファイルをreadすることができないのでしょうか。 どこがNGなのかわかりません。 追記すべき箇所があれば記載します。 アドバイスをお願いします。

  • デバッグしますか?というエラーメッセージ

    Microsoft Visual Studio 2005を入れてからなんですが、 他のプログラムを利用しているときたまに、 「ハンドルされていないWIN32の例外が発生しました」とメッセージが出て、 「利用可能なデバッガ」とでてそこの選択欄に「Microsoft Visual Studio 2005」 があります。 「選択したデバッガをデバッグしますか?」という項目で「はい」を選ぶと Microsoft Visual Studio 2005が立ち上がり、「いいえ」を選ぶと そのプログラムが強制終了します。 これは、なんでしょうか??困っています。

  • LISPで例外を発生させるには?

    LISPで例外を発生させるにはどうしたらよいのでしょうか? もしくは、プログラムを強制終了させたいです。 エラー発生時に警告を出して止めるのですが、後から捕捉できる形式にできたらよりベターです。 VBのraise Cでいう exit; です。

  • 同期するとエラーが発生します。

    音楽CDをWMPに取り込み、mp3プレーヤーに同期すると、うまく同期できるものもあれば、エラーが発生し「不明なエラーが検出されました。別のプログラムまたはオペレーティング システム コンポーネントで問題が発生し、その問題の本質がプレーヤーに通信されないときに、この問題が発生することがあります。」と出ます。何処を操作すれば同期できるようになりますか。ファイルは全てmp3ファイルです。

  • iostream インクルード時に発生するエラー

    C++ の勉強をするためにVisualStudio2008にて下記コードをビルドしたのですが、エラーが発生してビルドが失敗しました。 ■ コード #include <iostream> using namespace std; int main() { std::cout << "Hello World !"; return 0; } ■ 操作 空のコンソールアプリケーションを作成し、ソースファイルに追加>新しい項目 にて "temp.cpp" を追加、コードを入力。その後 ビルド > ソリューションのビルド を実行。 ■ エラー(一部) >> 「説明」 列 warning C4985: 'strlen': 前の宣言に属性が存在しません。 error C2039: 'wmemcpy_s' : '`global namespace'' のメンバではありません。 error C3861: 'wmemcpy_s': 識別子が見つかりませんでした error C2039: 'wmemmove_s' : '`global namespace'' のメンバではありません。 error C3861: 'wmemmove_s': 識別子が見つかりませんでした error C2039: 'memcpy_s' : '`global namespace'' のメンバではありません。 error C3861: 'memcpy_s': 識別子が見つかりませんでした error C2039: 'memmove_s' : '`global namespace'' のメンバではありません。 >>対応する「ファイル」列 d:\program files\microsoft visual studio 9.0\vc\include\exception d:\program files\microsoft visual studio 9.0\vc\include\iosfwd d:\program files\microsoft visual studio 9.0\vc\include\iosfwd d:\program files\microsoft visual studio 9.0\vc\include\iosfwd d:\program files\microsoft visual studio 9.0\vc\include\iosfwd d:\program files\microsoft visual studio 9.0\vc\include\iosfwd d:\program files\microsoft visual studio 9.0\vc\include\iosfwd d:\program files\microsoft visual studio 9.0\vc\include\iosfwd プロジェクトのプロパティやインストール時の構成などで何か問題があるのでしょうか。VisualStudio以外にはWindows SDK 、Windows SDK 6.0A、SQL Server2005などが導入されています。 再インストールするのもありかと思ったのですが、原因が分からないとまた同じ現象が発生しそうなため踏み切れません。 よろしくお願いします。