🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

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

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

13255閲覧

C言語で二次元配列のファイル読み込み

iamisa

総合スコア2

C

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

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/12/14 12:23

編集2020/12/14 12:39

C言語初心者です。
C言語でcsvファイルの読み込みを行いたいです。
csvファイルはイメージ説明上部の画像です。
このcsvファイルから各行の最後の数字のみを抜き出し、ファイルに書き出すということをしたいです。
現在その途中なのですが、以下のコードを試すと実行結果がdata[0][0]のみ数値が表示され、data[0][1]やその他の配列は全て0となってしまいます。どなたか教えていただきたいです、、。
また、配列に数値が入った後、どのようにして各行の最後の数値を抜き出せば良いかご教授よろしくお願いします、、。

#include <stdio.h> #define BUF_SIZE 256 int main(int argc, char *argv[]) { FILE *fp; char buf[BUF_SIZE]; int line = 0; if ((fp = fopen("Book1.csv", "r")) == NULL) { return -1; } while (fgets(buf, BUF_SIZE, fp) != NULL) { line++; } rewind(fp); // ★ または fseek(fp, 0, SEEK_SET); int data[10][8]; for(int i=0;i<10;i++){ for(int j=0;j<8;j++){ fscanf(fp,"%d ",&data[i][j]); } } printf("%d\n",data[0][0]); fclose(fp); return 0; }

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

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

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

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

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

guest

回答2

0

ベストアンサー

1行目は 2個、6行目は 5個。10行目は 4個ですね。
1行 8個を想定して読み込んではいけないのではありませんか?

fscanf の書式を "%d," に変更するだけではダメでしょう。

追記
fgets と strtol を使った例です。他にもやり方はあります。

C

1#include <stdio.h> // fopen, fclose, fgets, puts, printf, putchar 2#include <stdlib.h> // strtol 3 4#define BUF_SIZE 256 5#define LINE_SIZE 20 6#define FIELD_SIZE 16 7 8int main(void) 9{ 10 FILE *fp = fopen("Book1.csv", "r"); 11 if (fp == NULL) return 1; 12 13 char buf[BUF_SIZE]; 14 int line; 15 for (line = 0; fgets(buf, BUF_SIZE, fp); line++) ; 16 if (line > LINE_SIZE) { puts("too many lines"); return 2; } 17 18 rewind(fp); 19 20 int data[LINE_SIZE][FIELD_SIZE], count[LINE_SIZE]; 21 for (int i = 0; fgets(buf, BUF_SIZE, fp); i++) { 22 char *p = buf, *sep; 23 int j = 0; 24 while (j < FIELD_SIZE) { 25 data[i][j] = strtol(p, &sep, 10); 26 if (sep == p) break; 27 if (++j >= FIELD_SIZE) { puts("too many fields"); return 3; } 28 if (*sep != ',') break; 29 p = sep + 1; 30 } 31 count[i] = j; 32 } 33 fclose(fp); 34 35 for (int i = 0; i < line; i++) { 36 for (int j = 0; j < count[i]; j++) 37 printf("%10d", data[i][j]); 38 putchar('\n'); 39 } 40 return 0; 41}

投稿2020/12/14 13:36

編集2020/12/14 15:24
kazuma-s

総合スコア8224

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

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

iamisa

2020/12/14 13:45

各行の数が違うので、どのように考えばいいのかわからず、1行8個を想定してしまっていました。このような場合どのように考えれば良いのでしょうか?、、
iamisa

2020/12/14 15:45

ありがとうございます!!!とても参考になりました!
guest

0

CSVファイルという事は、コンマ区切りだと思いますが、

fscanf(fp,"%d ",&data[i][j]);

これではだめですね。

C言語のコードを書くなら、デバッグできる環境を整えましょう。
Eclipseや、WindowsならVisualStudioなど。
コードの任意の場所で実行を止め、変数のナカミを見ることができます。そこから1行づつ実行して、コードの流れを見れるようになります
そうすれば、アテズッポでコードを書かなくて済むようになります。

投稿2020/12/14 12:58

y_waiwai

総合スコア88040

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

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

iamisa

2020/12/14 13:43

確かに、コンマ区切りなのをわすれていました、、。ありがとうございます。
y_waiwai

2020/12/14 13:48

他の方の回答にもありますが、この修正だけでは無理ですね やるなら、1行づつ読み込んで、行単位で処理する、とかの工夫がいりそうです
iamisa

2020/12/14 14:53

1行ずつしか無理なんですね、、!ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問