• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:csvファイルの読み込みで失敗します)

csvファイルの読み込みで失敗する原因と対策

このQ&Aのポイント
  • csvファイルの行数、列数、要素数を取得するプログラムで、メモリ解放時にプログラムが落ちる問題が発生しています。
  • メモリ範囲外へのアクセスが原因である可能性がありますが、具体的なミスを特定できません。
  • csvファイルを読み込む際に含まれる小数の値に注意してください。

質問者が選んだベストアンサー

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

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()した時にオーバーラン。

Kumakko3
質問者

お礼

回答ありがとうございます。 ヌル文字の分を忘れていました。 ファイルサイズは正しく返しているようなので、 文字列最後に加わるヌル文字の分+1して、str = new char[fsize+1];とすれば大丈夫でしょうか。 プログラムとしては動くようになったのですが、正しく理解しているか不安なもので。 strcatの部分の違和感というのも、ヌル文字の分を入れていないからでしょうか?以下のようにすればいいのでしょうか?それとも根本的に使い方がいまいちなのでしょうか? strncat( str, buf, strlen(buf)+1 );

その他の回答 (6)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.7

ああ, 確かに「全部覚えておく」必要はないですね>#5. そして, 「ファイルを全部記憶できる」だけのメモリを確保しているなら fgets を while でまわす必要がない, と.

Kumakko3
質問者

お礼

コメントありがとうございます。 別の方法での実装も考慮できるようにしていきたいと思います。

  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.6

>strcatの部分の違和感というのも、ヌル文字の分を入れていないからでしょうか?以下のようにすればいいのでしょうか?それとも根本的に使い方がいまいちなのでしょうか? >strncat( str, buf, strlen(buf)+1 ); バッファオーバーランしない限りはstrcat()でいいでしょう? そして、今回は(仕様として正しい値が取れるかは不明とはいえ)ファイルサイズ+α分のバッファを動的確保しているのですから、 strncat()にする必要もない…かと思うんですが……。 strncat()の使いどころって… 「コピー先(連結先)よりコピー元の文字列長が長い場合に途中で切れてでもバッファオーバーランさせない」って場合かと思いますが。 # まぁ、元々何文字入っているのかわからないと使いにくいですが。 # strncat( str, buf, (sizeof(str) - strlen(str) - 1) ) って感じ…かな??

Kumakko3
質問者

お礼

親切なご指導ありがとうございます。 strcatとstrncatなど各関数の違いを意識していきます。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.5

順番に読んで順番に処理するだけなら、strそのものを使わずに // 要素数、行数、列数の取得 while((c=fgetc(fp))!=EOF){ switch( c ){ ... で十分な気がします。

Kumakko3
質問者

お礼

回答ありがとうございます。 確かに順に読んで、文字数をカウントするだけならfgetcでよかったですね。 そのあと、取得した文字列から次のカンマまたは改行までの文字列分を取ってきてstrtod関数でdoubleに変換するときに文字列がいいのかと思って、そうしてしまっていました。

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.4

#1ですが、その補足に対しての回答です。 テキストモードで開けたファイルに対するftell()で取れるのは(大雑把に言えば)「文字数」ですよね。 文字列を格納するのに必要な大きさは、本当にその文字数だけでよかったのかなぁ? ……というか、#3さんが答え書いてますね。

Kumakko3
質問者

お礼

補足していただきありがとうございます。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

#1 に加えて, そもそも ftell を使って何をしたいのかが既に疑問.

Kumakko3
質問者

お礼

回答ありがとうございます。 fopenでファイルを開いて、fseek( fp, 0L, SEEK_END );でファイルの終端までポインタを移動して、ftellすることで、ファイルのサイズが取得できると思って書いていましたが、考え方が間違っているのでしょうか? ファイルサイズの取得はテキストの文字数を取得したいと思って行なっています。

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.1

> // ファイルサイズに合わせて文字列領域確保 > char *str; > str = new char[fsize]; 本当にその大きさでいいのかなぁ? 文字列なんだから……ねぇ?

Kumakko3
質問者

お礼

ご指摘ありがとうございます。 csvファイルに書かれている文字数に応じて、文字列領域を確保するにはどのようなコードを書けばいいのかわかっていないので、教えていただけると助かります。