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

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

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

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

Q&A

解決済

3回答

2820閲覧

fscanfがうまく動作しない

Gargantua

総合スコア17

C

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

0グッド

0クリップ

投稿2017/11/03 08:10

###前提・実現したいこと
テキストファイルから情報を取り込みたい。
中身は
Dbrenlhsij,11,162.2,55.9
Ijnpwthy,14,163.8,62.6
Csaztvsy,30,176.2,57.1
Pgqfcwlx,22,161.2,57.3
Mgjwpmdxr,19,162.,65.2
Jryebcpduv,54,167.2,55.2
Dqesqocy,22,169.,64.9
というように続いていきます。(10000行あります)

fgetsを使ってstrtokでも同じことができると思いますが、学習のためにfscanfを使った方法が知りたいです。またなぜこれでは値がとりこめないのかを教えていただきたいです。

###発生している問題・エラーメッセージ
fscanf(46行目)が値をとりこまない。
結果としてprintfで出力する変数は全て0.0になっています。

###該当のソースコード

c

1 2#include <stdio.h> 3#include <math.h> 4#include <stdlib.h> 5 6#define SIZE 100 7 8void cal(double*,double*,double*,double*,double*,int); 9 10int main(int argc,char *argv[]){ 11 FILE *fp; 12 int line=0; 13 char c; 14 15 if(argc!=2) { 16 printf("コマンドの後に1つファイルを指定してください。\n"); 17 return 1; 18 } 19 20 if ((fp= fopen(argv[1], "r"))==NULL) { 21 printf("ファイルを開くのに失敗しました\n"); 22 return 1; 23 } 24 25 while((c = getc(fp)) != EOF) { 26 if(c == '\n') { 27 line++; 28 } 29 } 30 31 fseek(fp,0,SEEK_SET); 32 33 double *a; 34 double *h; 35 double *w; 36 double *max,*min,*mean,*stdev; 37 38 max=(double*)malloc(sizeof(double)); 39 min=(double*)malloc(sizeof(double)); 40 mean=(double*)malloc(sizeof(double)); 41 stdev=(double*)malloc(sizeof(double)); 42 a=(double*)malloc(sizeof(double)*line); 43 h=(double*)malloc(sizeof(double)*line); 44 w=(double*)malloc(sizeof(double)*line); 45 46 for (int i=0; i<line; i++) { 47 fscanf(fp,"%*[^,]%lf,%lf,%lf\n",a+i,h+i,w+i); 48 } 49 50 cal(a,max,min,mean,stdev,line); 51 printf("Age : (max,min,mean,stdev) = (%lf, %lf, %lf, %lf)\n", 52 *max,*min,*mean,*stdev); 53 54 cal(h,max,min,mean,stdev,line); 55 printf("Age : (max,min,mean,stdev) = (%lf, %lf, %lf, %lf)\n", 56 *max,*min,*mean,*stdev); 57 58 cal(w,max,min,mean,stdev,line); 59 printf("Age : (max,min,mean,stdev) = (%lf, %lf, %lf, %lf)\n", 60 *max,*min,*mean,*stdev); 61 62 free(max); 63 free(min); 64 free(mean); 65 free(stdev); 66 free(a); 67 free(h); 68 free(w); 69 70 fclose(fp); 71 72 return 0; 73} 74 75void cal(double *x,double *max,double *min,double *mean,double *stdev,int line){ 76 *max=0,*min=1000,*mean=0,*stdev=0; 77 78 for (int i=0; i<line; i++) { 79 if ( *(x+i) > *max) { 80 *max = *(x+i); 81 } 82 if ( *(x+i) < *min) { 83 *min = *(x+i); 84 } 85 *mean= *mean + *(x+i); 86 } 87 *mean = *mean/line; 88 for (int i=0; i<line; i++) { 89 *stdev= *stdev + pow(*(x+i)-*mean,2); 90 } 91 *stdev= sqrt( *stdev/(double)line ); 92} 93

###試したこと
fscanfの返り値を調べたところ毎回0でした。デバッガを用いて動きを追ってみたのですがやはりfscanfが問題のようです。

###補足情報(言語/FW/ツール等のバージョンなど)
OS Xです。

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

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

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

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

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

guest

回答3

0

読み込みの部分のみでたの部分までは見ておりませんでご参考にどうぞ
読み飛ばししたかったのですね、修正しました。

int i; for (i=0; i<line; i++) { fscanf(fp,"%*[^,],%lf,%lf,%lf\n",a+i,h+i,w+i); printf("%lf %lf %lf\n",*(a+i),*(h+i),*(w+i)); }

投稿2017/11/03 10:14

編集2017/11/03 11:04
A.Ichi

総合スコア4070

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

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

0

回答ではないですが、

C

1clang -pipe -Weverything -Ofast -c "untitled.c"(ディレクトリ: /home/kondo/test/ctst) 2untitled.c:48:16: warning: implicit conversion loses integer precision: 'int' to 'char' [-Wconversion] 3 while((c = getc(fp)) != EOF) { 4 ~ ^~~~~~~~ 5/usr/include/stdio.h:523:35: note: expanded from macro 'getc' 6#define getc(fp) (!__isthreaded ? __sgetc(fp) : (getc)(fp)) 7 ^~~~~~~~~~~ 8/usr/include/stdio.h:480:37: note: expanded from macro '__sgetc' 9#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++)) 10 ^~~~~~~~~~ 11untitled.c:48:16: warning: implicit conversion loses integer precision: 'int' to 'char' [-Wconversion] 12 while((c = getc(fp)) != EOF) { 13 ~ ^~~~~~~~ 14/usr/include/stdio.h:523:35: note: expanded from macro 'getc' 15#define getc(fp) (!__isthreaded ? __sgetc(fp) : (getc)(fp)) 16 ^~~~~~~~~~~ 17/usr/include/stdio.h:480:50: note: expanded from macro '__sgetc' 18#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++)) 19 ^~~~~~~~~~~~~~~~~ 20untitled.c:48:16: warning: implicit conversion loses integer precision: 'int' to 'char' [-Wconversion] 21 while((c = getc(fp)) != EOF) { 22 ~ ^~~~~~~~ 23/usr/include/stdio.h:523:49: note: expanded from macro 'getc' 24#define getc(fp) (!__isthreaded ? __sgetc(fp) : (getc)(fp)) 25 ^~~~~~~~~~ 26untitled.c:65:38: warning: implicit conversion changes signedness: 'int' to 'unsigned long' [-Wsign-conversion] 27 a=(double*)malloc(sizeof(double)*line); 28 ~^~~~ 29untitled.c:66:38: warning: implicit conversion changes signedness: 'int' to 'unsigned long' [-Wsign-conversion] 30 h=(double*)malloc(sizeof(double)*line); 31 ~^~~~ 32untitled.c:67:38: warning: implicit conversion changes signedness: 'int' to 'unsigned long' [-Wsign-conversion] 33 w=(double*)malloc(sizeof(double)*line); 34 ~^~~~ 35untitled.c:99:11: warning: possible misuse of comma operator here [-Wcomma] 36 *max=0,*min=1000,*mean=0,*stdev=0; 37 ^ 38untitled.c:99:5: note: cast expression to void to silence warning 39 *max=0,*min=1000,*mean=0,*stdev=0; 40 ^~~~~~ 41 (void)( ) 42untitled.c:99:21: warning: possible misuse of comma operator here [-Wcomma] 43 *max=0,*min=1000,*mean=0,*stdev=0; 44 ^ 45untitled.c:99:12: note: cast expression to void to silence warning 46 *max=0,*min=1000,*mean=0,*stdev=0; 47 ^~~~~~~~~ 48 (void)( ) 49untitled.c:99:29: warning: possible misuse of comma operator here [-Wcomma] 50 *max=0,*min=1000,*mean=0,*stdev=0; 51 ^ 52untitled.c:99:22: note: cast expression to void to silence warning 53 *max=0,*min=1000,*mean=0,*stdev=0; 54 ^~~~~~~ 55 (void)() 56untitled.c:29:9: warning: macro is not used [-Wunused-macros] 57#define SIZE 100 58 ^ 5910 warnings generated. 60コンパイル完了

(-Weverything)設定してるのでかなり厳しいですが、これだけワーニングがでます。確認しましたか? こちらの環境はFreeBSD clang version 4.0です。
また、while((c = getc(fp)) != EOF) はcがcharなのでEOFが判定できません。getc()の返り値はintです。・・・空読みするだけならfgets()がいいですよ。fscanf()も読み込んだ項目数が返るので読めたかどうか判定してください。

投稿2017/11/03 09:36

cateye

総合スコア6851

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

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

0

ベストアンサー

書式指定文字列 "%*[^,],%lf,%lf,%lf\n" でいかがでしょう。1つ目のフィールド(%*[^,])の次に,の読み捨て指定が必要なはずです。

投稿2017/11/03 09:25

yohhoy

総合スコア6191

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問