- ベストアンサー
csvファイルの読み込みで失敗する原因と対策
- csvファイルの行数、列数、要素数を取得するプログラムで、メモリ解放時にプログラムが落ちる問題が発生しています。
- メモリ範囲外へのアクセスが原因である可能性がありますが、具体的なミスを特定できません。
- csvファイルを読み込む際に含まれる小数の値に注意してください。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
http://support.microsoft.com/kb/68337/ja http://msdn.microsoft.com/ja-jp/library/0ys3hc0b%28v=vs.80%29.aspx とかですかね。>#2 私的には… >strncat( str, buf, strlen(buf) ); もちょっとばかし違和感が。 # ありといえばあり…なんでしょうけど。 >終わりのメモリ解放であるdelete []strのところでプログラムが落ちてしまいます。範囲外のメモリにアクセスしてしまっているのかと は、回答ある通り…ですかね。 ftell()が正しくファイルサイズを返している場合は…'\0'の分が足りない。 ファイルサイズが正しくなかった場合は…strncat()した時にオーバーラン。
その他の回答 (6)
- Tacosan
- ベストアンサー率23% (3656/15482)
ああ, 確かに「全部覚えておく」必要はないですね>#5. そして, 「ファイルを全部記憶できる」だけのメモリを確保しているなら fgets を while でまわす必要がない, と.
お礼
コメントありがとうございます。 別の方法での実装も考慮できるようにしていきたいと思います。
- Wr5
- ベストアンサー率53% (2173/4061)
>strcatの部分の違和感というのも、ヌル文字の分を入れていないからでしょうか?以下のようにすればいいのでしょうか?それとも根本的に使い方がいまいちなのでしょうか? >strncat( str, buf, strlen(buf)+1 ); バッファオーバーランしない限りはstrcat()でいいでしょう? そして、今回は(仕様として正しい値が取れるかは不明とはいえ)ファイルサイズ+α分のバッファを動的確保しているのですから、 strncat()にする必要もない…かと思うんですが……。 strncat()の使いどころって… 「コピー先(連結先)よりコピー元の文字列長が長い場合に途中で切れてでもバッファオーバーランさせない」って場合かと思いますが。 # まぁ、元々何文字入っているのかわからないと使いにくいですが。 # strncat( str, buf, (sizeof(str) - strlen(str) - 1) ) って感じ…かな??
お礼
親切なご指導ありがとうございます。 strcatとstrncatなど各関数の違いを意識していきます。
- kmee
- ベストアンサー率55% (1857/3366)
順番に読んで順番に処理するだけなら、strそのものを使わずに // 要素数、行数、列数の取得 while((c=fgetc(fp))!=EOF){ switch( c ){ ... で十分な気がします。
お礼
回答ありがとうございます。 確かに順に読んで、文字数をカウントするだけならfgetcでよかったですね。 そのあと、取得した文字列から次のカンマまたは改行までの文字列分を取ってきてstrtod関数でdoubleに変換するときに文字列がいいのかと思って、そうしてしまっていました。
- hitomura
- ベストアンサー率48% (325/664)
#1ですが、その補足に対しての回答です。 テキストモードで開けたファイルに対するftell()で取れるのは(大雑把に言えば)「文字数」ですよね。 文字列を格納するのに必要な大きさは、本当にその文字数だけでよかったのかなぁ? ……というか、#3さんが答え書いてますね。
お礼
補足していただきありがとうございます。
- Tacosan
- ベストアンサー率23% (3656/15482)
#1 に加えて, そもそも ftell を使って何をしたいのかが既に疑問.
お礼
回答ありがとうございます。 fopenでファイルを開いて、fseek( fp, 0L, SEEK_END );でファイルの終端までポインタを移動して、ftellすることで、ファイルのサイズが取得できると思って書いていましたが、考え方が間違っているのでしょうか? ファイルサイズの取得はテキストの文字数を取得したいと思って行なっています。
- hitomura
- ベストアンサー率48% (325/664)
> // ファイルサイズに合わせて文字列領域確保 > char *str; > str = new char[fsize]; 本当にその大きさでいいのかなぁ? 文字列なんだから……ねぇ?
お礼
ご指摘ありがとうございます。 csvファイルに書かれている文字数に応じて、文字列領域を確保するにはどのようなコードを書けばいいのかわかっていないので、教えていただけると助かります。
お礼
回答ありがとうございます。 ヌル文字の分を忘れていました。 ファイルサイズは正しく返しているようなので、 文字列最後に加わるヌル文字の分+1して、str = new char[fsize+1];とすれば大丈夫でしょうか。 プログラムとしては動くようになったのですが、正しく理解しているか不安なもので。 strcatの部分の違和感というのも、ヌル文字の分を入れていないからでしょうか?以下のようにすればいいのでしょうか?それとも根本的に使い方がいまいちなのでしょうか? strncat( str, buf, strlen(buf)+1 );