プロが教える店舗&オフィスのセキュリティ対策術

C言語を勉強中です。
下記のcsvファイルを読み込みたいのですが、
---------------------------------
言葉\n
言葉,記号\n
空白の行\n
言葉\n
空白、数字、数字、数字\n
数字、数字、数字、数字EOF
---------------------------------
表示が
---------------------------------
言葉
意味不明な文字……
---------------------------------
となります。正しく読めるのは1つめのみです。
読み取りたいのは数字だけなので上から5行目から読み込む方法、と空欄を読み飛ばす方法を教えてください。もしくは正しく読み込む方法を教えてください。

現在は
fp=fopen("test.csv","r");
fscanf(fp,"%[^,],%[^,],%[^,],%[^,],%lf,%lf,%lf,%lf,%lf,%lf,%lf",&a,&b,&c,&d,&n1,&n2,&n3,&n4,&n5,&n6,&n7);
printf("%s,%s,%s,%s,%f,%f,%f,%f,%f,%f,%f\n",a,b,c,d,n1,n2,n3,n4,n5,n6,n7);
と書いています。
空欄の読み方、改行を読むときがおかしいということは何となく分かるのですがどう修正すればよいのかわかりません。
また、%[^,]を使用せず、%sを使用して1行丸々読み込んでもいいのですが、その場合も1行目のみ正しく読み込まれ、2行目以降は意味不明な記号の羅列が表示されてしまいます。
よろしくお願いします。

質問者からの補足コメント

  • うーん・・・

    回答ありがとうございます。コピペして試してみたのですが、まったく関係のない数字が表示されます。読めていないようです。tatsu99さんはこちらのプログラムで実行結果が正しく表示されるのでしょうか? 回答お待ちしています。

    No.3の回答に寄せられた補足コメントです。 補足日時:2015/09/22 23:37
  • うーん・・・

    csvファイルをメモ帳で開いたときのモノをコピペしています。
    tatsu99さんのプログラムではもう少し長いものを読んでいましたが、今は
    試しに少ない数字で試しているのですがうまくいきませんでした。
    下記にcsvファイルの中身を示しておきます。
    よろしくお願いします。
    ---------------------
    ???,
    ????,####
    ,
    ?,
    10,11
    21,22
    ---------------------

    No.4の回答に寄せられた補足コメントです。 補足日時:2015/09/23 00:38

A 回答 (7件)

a,b,c,d,n1,n2,n3,n4,n5,n6,n7


の宣言がわからなければ、なんとも言えません。


ただ。
fscanf(fp,"%[^,],%[^,],%[^,],%[^,],%lf,%lf,%lf,%lf,%lf,%lf,%lf",&a,&b,&c,&d,&n1,&n2,&n3,&n4,&n5,&n6,&n7);
で、 %s に対応する変数の型は char *, char[]等です。

&a,&b,&c,&d としていますが、これは変数 a,b,c,dへのポインタとなります。
&a が char * なら、 aは char です。

対して
printf("%s,%s,%s,%s,%f,%f,%f,%f,%f,%f,%f\n",a,b,c,d,n1,n2,n3,n4,n5,n6,n7);
としたときの %s に対応したa,b,c,d の求められるのは 、char * や char[]等の「文字列(として使われるポインタや配列)」です。

あきらかに、型が矛盾しています
    • good
    • 0
この回答へのお礼

ご指摘ありがとうございます。まだまだ勉強不足で型が矛盾していることに気が付きませんでした。宣言はchar[]で行っています。修正してみます!

お礼日時:2015/09/22 23:40

とりあえず scanf の返り値について調べるべし.



あと, scanf は型について気にしない (というか気にしようがない) ので
char buf[100];
scanf("%s", &buf);
は結果的に正しく動いてしまうという驚愕の事実>#1.
    • good
    • 0
この回答へのお礼

scanf("%s", &buf);はエラーではなく、動くのですね。返り値についてもう一度勉強しなおしてみます。ありがとうございます。

お礼日時:2015/09/22 23:42

以下のようにしてください。


-------------------------------------------
#include <stdio.h>
int main(void){

FILE *fp;
double d11,d12,d13;
double d21,d22,d23,d24;
if((fp = fopen("test.csv","r"))==NULL){
printf("not open\n");
}
fscanf(fp,"%*s"); //1行空読み
fscanf(fp,"%*s"); //1行空読み
fscanf(fp,"%*s"); //2行空読み(空白行も含めて空読みする為、2行空読みする)

fscanf(fp," ,%lf,%lf,%lf",&d11,&d12,&d13);
fscanf(fp,"%lf,%lf,%lf,%lf",&d21,&d22,&d23,&d24);

fclose(fp);
//確認用
printf("<%f><%f><%f>\n",d11,d12,d13);
printf("<%f><%f><%f><%f>\n",d21,d22,d23,d24);
return 0;
}
-------------------------------------------
test.csvの内容が、以下の場合
-------------------------------------
言葉1
言葉2,#

言葉3
,11,12,13
21,22,23,24
--------------------------------------
実行結果
<11.000000><12.000000><13.000000>
<21.000000><22.000000><23.000000><24.000000>
となります。
この回答への補足あり
    • good
    • 0

>tatsu99さんはこちらのプログラムで実行結果が正しく表示されるのでしょうか?


私が作成したtest.csvを読み込んだ場合は、正しく表示されます。
あなたが作成したtest.csvをここに提示していただけますでしょうか。
今回、行数も関係しますので、それも正しく把握したいので
---------------------------
test.csvの内容
---------------------------
のように、test.csvの内容の前後を--------------------ではさんでください。

又、空白とは、半角の空白と理解しています。
もし、全角の空白の場合は、正しく読み込めません。その場合は、fscanfのやりかたを変える必要があります。
全角の空白の場合は、その旨、補足してください。
この回答への補足あり
    • good
    • 0

提示された行の


5行目は、空白、数字、数字、数字\n
6行目は、数字、数字、数字、数字EOF
のはずです。
あなたが提示されたデータは
10,11
21,22
となっています。
これを
空白,10,11,12    ・・・半角空白と12を追加(カンマは半角カンマ)(5行目)
21,22,23,24    ・・・23と24を追加(カンマは半角カンマ)(6行目)
としてください。
そうすれば、
<11.000000><12.000000><13.000000>
<21.000000><22.000000><23.000000><24.000000>
と表示されるはずです。
    • good
    • 0

#5です。


すみません。もう一行修正すべき行があります。
3行目は ,ですが、この行は空白行のはずです。
カンマをとり、改行だけの行にして下さい。
結局、正しいデータは以下のようになります。
------------------------------
???,
????,####

?,
,11,12,13
21,22,23,24
-------------------------------
    • good
    • 0
この回答へのお礼

読み込むことができました。ありがとうございます!

お礼日時:2015/09/24 00:08

既に書かれてるけど, もともとの質問にあった


言葉\n
言葉,記号\n
空白の行\n
言葉\n
空白、数字、数字、数字\n
数字、数字、数字、数字EOF
という形と「csvファイルをメモ帳で開いたときのモノ」である
???,
????,####
,
?,
10,11
21,22
が全く違うって理解できる?

それはさておき, 本当はどういう形なんだ? まさかここでまた違う形を出して「本当はこうです」とか言わないだろうな?

以下本題ではないけど誤解するといけないので補足.

char buf[100];
scanf("%s", &buf);
が「正しく」動くとはいっても, それはあくまで「結果的に」であって, 論理的には間違っています. これが「正しいプログラムである」とは思わないでください.
    • good
    • 0
この回答へのお礼

ありがとうございます。自分でも調べなおしてみました!

お礼日時:2015/09/24 00:06

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!