質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

3回答

5375閲覧

C言語で任意のcsvファイルを配列に格納したい

yukatii

総合スコア5

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2022/05/29 18:05

実現したいこと

タイトルにある通り、C言語で任意のcsvファイル(ただしデータは1行)を配列に格納したいです。
csvファイルの例は次のような感じです。

1,2,3,4,5, ...

扱うcsvファイルは全て1行のデータですが、データの数が変わっても対応できるようにしたいです。

発生している問題・エラーメッセージ

配列に格納した結果が表示されません。

該当のソースコード

csvファイルの中身は小数を想定しているので、double型配列を用いています。

#include <stdio.h> #include <stdlib.h> #define N 256 int main(void) { FILE *fp; // FILE型構造体 char fname[] = "brain_waves.csv"; double f[N] = {}; int n; fp = fopen(fname, "r"); // ファイルを開く。失敗するとNULLを返す。 if(fp == NULL) { printf("%s file not open!\n", fname); return -1; } while ( ! feof(fp) && n < N) { fscanf(fp, "%lf", &(f[n])); n++; printf("%lf",f[n]); } fclose(fp); // ファイルを閉じる return 0; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2022/05/29 19:37

, を読み飛ばしてなかったり、表示する前に n++ してるからでは…。
setoppu

2022/05/29 21:36

ついでにnの初期値はいくつなんでしょう。
shsh_

2022/05/31 11:30 編集

本当に「任意のcsvファイル」を読み込みたいのでしょうか? それともカンマ区切りされた複数の数値が取得できさえすればよいのでしょうか? 前者と後者とでは難易度が全く異なります。 「実現したいこと」の内容と「該当のソースコード」の内容が乖離していて、どちらを実現したいのかが分かりません。
guest

回答3

0

n0 で初期化すること、nprintf()のあとに増加させること、あとscanf() の使い方を以下のようにすれば動くかと思います。

c

1 // , 付きで試してみて、 2 if (fscanf(fp, "%lf,", &f[n]) < 1) { 3 // ダメなら , なしでもう一度 4 if (fscanf(fp, "%lf", &f[n]) < 1) 5 break; // まだダメならループを終了 6 }

投稿2022/05/30 03:02

int32_t

総合スコア21929

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

とりあえず,原始的に(?) 1文字ずつ読み込むような処理を考えてみてはどうでしょうか.

ファイルから1文字取ってきて,
カンマじゃなかったらバッファにため込む.
カンマだったら,その直前までにバッファにたまった内容が1個の数値を表すハズだから…
みたいな.

仮に何かしらの意味でより{かっこいい(?),効率的(?),etc}な実装形態を目指したいのだとしても,まずはある程度動く単純なのを作ってから→それを足掛かりにして改造なりしていけば良いのではないでしょうか.

C

1#define N (256) 2#define MAX_WORD_LENGTH (64) 3 4//文字列を double に解釈する作業. 5double CvtWordToDouble( const char *Word ) 6{ 7 //※ 8 //この実装では「解釈できない」文字列が来た場合のことを何も考えずに, 9 //単に atof を使う. 10 // 11 double d = atof( Word ); 12 printf( "[%s] -> %f\n", Word, d ); 13 return d; 14} 15 16//main 17int main( int argc, const char *argv[] ) 18{ 19 double f[N] = {}; 20 int nReadValue = 0; 21 { 22 const char fname[] = "data.txt"; 23 FILE *fp = fopen(fname, "r"); 24 if (fp == NULL) 25 { 26 printf("%s file not open!\n", fname); 27 return -1; 28 } 29 30 int WordLength = 0; 31 char Word[MAX_WORD_LENGTH] = { 0 }; //バッファ 32 int c; 33 while( (c = fgetc(fp)) != EOF ) //1文字ずつ読む 34 { 35 if( c == ',' ) 36 {//カンマが来たなら現在のバッファの中身が1つの数値を表すハズ 37 Word[WordLength] = '\0'; 38 f[nReadValue++] = CvtWordToDouble(Word); 39 WordLength = 0; 40 } 41 else 42 {//バッファにためる 43 Word[WordLength++] = c; 44 if( WordLength >= MAX_WORD_LENGTH ) 45 { 46 printf( "Unexpected Input\n" ); 47 return -1; 48 } 49 } 50 } 51 52 fclose(fp); 53 54 if( WordLength > 0 ) //行末の要素に対する処理 55 { 56 Word[WordLength] = '\0'; 57 f[nReadValue++] = CvtWordToDouble(Word); 58 } 59 } 60 61 printf( "%d values read.\n", nReadValue ); 62 return 0; 63}

投稿2022/05/30 02:26

fana

総合スコア12151

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2022/05/30 02:30

ありゃ, MAX_WORD_LENGTH ってのは変な名称だな… (まぁどうでもいいが)
guest

0

fscanf(fp, "%lf", &(f[n]));


fscanf(fp, "%lf,", &(f[n]));
とすれば、ある程度は進むだろうけど、行末でコケますね
そもそもCSVの取り込みにscanf使うのはだめです。
そこらへんの考え方から変えないとダメかと。

投稿2022/05/30 00:59

y_waiwai

総合スコア88163

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問