以下のようなソースでカンマ区切りのテキストファイルであるcsvファイルの行数、列数、要素数を取得するプログラムを作っているのですが、終わりのメモリ解放であるdelete []strのところでプログラムが落ちてしまいます。範囲外のメモリにアクセスしてしまっているのかと思いますが、ミスを特定できないので、教えてください。
読み込むcsvファイルには以下のような小数の値が入っています。
0.23960810421811729043, 11.753428210139766463, …(省略) , 3.8736893050771881164
int main( int argc, char **argv ) {
int csvRowNum, csvColNum, csvElemNum;
GetCSVDataNum ( "C:\\Data.csv", csvRowNum, csvColNum, csvElemNum );
return 0;
}
// csvファイルから行数、列数、要素数を取得する
int GetCSVDataNum ( char *csv_name, int &rowNum, int &colNum, int &elemNum ) {
FILE *fp;
fp = fopen( csv_name, "r" );
if( fp == NULL ){
printf( "ファイルオープンエラー\n" );
exit(1);
}
// ファイルサイズの取得
int fsize;
fseek( fp, 0L, SEEK_END );
fsize = ftell( fp );
// ファイルシーク位置を先頭に戻す
fseek( fp, 0L, SEEK_SET );
// ファイルサイズに合わせて文字列領域確保
char *str;
str = new char[fsize];
char buf[10000];
// ファイルから1行ずつテキストデータを読み込み、
// 連結してbufに格納する
str[0] = '\0';
while ( fgets( buf, sizeof(buf), fp ) != NULL ) {
strncat( str, buf, strlen(buf) );
}
int countSep = 0;// '(カンマ)の数のカウント
int cols = 0;// 各行の列数をカウント
int countNL = 0;// 改行の数をカウント
// 要素数、行数、列数の取得
for ( int i = 0; i < (int)strlen(str); i++ ) {
switch( str[i]){
case ',':
countSep++;
cols++;
break;
case '\n':
countNL++;
cols++;
// 各行で列数が異なるときは、最も大きい列数とする
colNum = (colNum > cols ) ? colNum: cols;
cols = 0;
break;
default:
break;
}
}
rowNum = countNL;
elemNum = countSep + countNL;
// strの解放で落ちる
delete[] str;
fclose( fp );
return 0;
}
No.3ベストアンサー
- 回答日時:
http://msdn.microsoft.com/ja-jp/library/0ys3hc0b …
とかですかね。>#2
私的には…
>strncat( str, buf, strlen(buf) );
もちょっとばかし違和感が。
# ありといえばあり…なんでしょうけど。
>終わりのメモリ解放であるdelete []strのところでプログラムが落ちてしまいます。範囲外のメモリにアクセスしてしまっているのかと
は、回答ある通り…ですかね。
ftell()が正しくファイルサイズを返している場合は…'\0'の分が足りない。
ファイルサイズが正しくなかった場合は…strncat()した時にオーバーラン。
回答ありがとうございます。
ヌル文字の分を忘れていました。
ファイルサイズは正しく返しているようなので、
文字列最後に加わるヌル文字の分+1して、str = new char[fsize+1];とすれば大丈夫でしょうか。
プログラムとしては動くようになったのですが、正しく理解しているか不安なもので。
strcatの部分の違和感というのも、ヌル文字の分を入れていないからでしょうか?以下のようにすればいいのでしょうか?それとも根本的に使い方がいまいちなのでしょうか?
strncat( str, buf, strlen(buf)+1 );
No.4
- 回答日時:
#1ですが、その補足に対しての回答です。
テキストモードで開けたファイルに対するftell()で取れるのは(大雑把に言えば)「文字数」ですよね。
文字列を格納するのに必要な大きさは、本当にその文字数だけでよかったのかなぁ?
……というか、#3さんが答え書いてますね。
No.6
- 回答日時:
>strcatの部分の違和感というのも、ヌル文字の分を入れていないからでしょうか?以下のようにすればいいのでしょうか?それとも根本的に使い方がいまいちなのでしょうか?
>strncat( str, buf, strlen(buf)+1 );
バッファオーバーランしない限りはstrcat()でいいでしょう?
そして、今回は(仕様として正しい値が取れるかは不明とはいえ)ファイルサイズ+α分のバッファを動的確保しているのですから、
strncat()にする必要もない…かと思うんですが……。
strncat()の使いどころって…
「コピー先(連結先)よりコピー元の文字列長が長い場合に途中で切れてでもバッファオーバーランさせない」って場合かと思いますが。
# まぁ、元々何文字入っているのかわからないと使いにくいですが。
# strncat( str, buf, (sizeof(str) - strlen(str) - 1) ) って感じ…かな??
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- C言語・C++・C# #include <stdio.h>int main(void) { int buf[100] = 6 2022/11/01 22:45
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語で再起関数とポインタを用いて文字列反転をする方法がわかりません。 4 2023/04/29 20:32
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
なぜCSQとCIP形式ではコ...
-
複数ファイルの同時読み込みの...
-
ファイルが読み込めない・・・
-
c言語 ファイルから数字を読み...
-
日本語ファイル名のFTPについて
-
C言語を用いて、csvファイル内...
-
fgets( ) の返り値は何?
-
ガンマ変換 C言語でプログラ...
-
C言語でのCSVソートとデータ抽...
-
C言語でファイル読み書きを早く...
-
構造体とファイル検索(><)
-
音声データを出力するCプログラ...
-
lockfについて
-
画像を読み込み、画素値の度数...
-
ファイルへの書込み処理が異常...
-
乱数とファイルの入出力の質問...
-
csvfファイルの1行目と3行目を...
-
テキストファイル内に対して, ...
-
C言語におけるファイル読み込み...
-
#define _CRT_SECURE_NO_WARNIN...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
c言語でのfscanfについて
-
C言語でファイル読み書きを早く...
-
fopenでファイル名に、変数を使...
-
複数ファイルの同時読み込みの...
-
fgets( ) の返り値は何?
-
テキストファイル内に対して, ...
-
ファイルへの書込み処理が異常...
-
C言語にてXMLファイルから任意...
-
ファイル出力で改行を入れたい!
-
C言語でセグメンテーションエ...
-
エラーがわかりません、、
-
ガンマ変換 C言語でプログラ...
-
自己相関関数を求めるプログラ...
-
VisualStudioでのファイルの入...
-
同時にファイル読み込み 書き込み
-
c言語 ファイルから数字を読み...
-
大量の入力ファイルを扱うとき...
-
ファイルが読み込めない・・・
-
【C言語】ファイルを読み込んで...
-
a*(1-exp(-bx))+cの近似の方法
おすすめ情報