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

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

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

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

Q&A

解決済

3回答

521閲覧

平均値プログラムsscanfの返り値で、、、。

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

0グッド

0クリップ

投稿2018/08/09 04:07

編集2018/08/09 04:20
1 #include <stdio.h> 2 #include <string.h> 3 int main (){ 4 5 int n = 0,y = 1; 6 float x; 7 float average = 0; 8 9 10 fgets(s,sizeof(s),stdin); 11 n = sscanf(s,"%f",&x); 12 13 for(int i = 0;i != n + 1;i++){ 14 15 average += s[i]; 16 17 } 18 19 average = average /n; 20 21 printf("平均は%fです\n",average); 22 23 return 0; 24 }

任意の数の数値を打ち込んで打ち込んだ数すべて足した後、打ち込んだ数だけ割って平均を出そうとしたのですが、なかなかうまくいかなくて、、、。
sscanfが打ち込んだ数だけ返り値として返してくれるのでそれをもとにプログラムを書こうと思いました。もっといいやり方があるのは知っているのですが、sscanfの返り値のもとできるようにしたいです。できそうな、案のある方ぜひよろしくお願いします!
ちなみに10と11行目が怪しくてできないです。

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

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

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

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

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

guest

回答3

0

ベストアンサー

sscanfで出来ます

c

1#include <stdio.h> 2 3int main(){ 4 char s[4096]; 5 fgets(s, sizeof(s), stdin); 6 7 int n, offset = 0, count = 0; 8 float f, sum = 0.0; 9 while(sscanf(s+offset, "%f%n", &f, &n) == 1){ 10 sum += f; 11 count++; 12 offset += n; 13 } 14 printf("合計: %f\n平均: %f\n", sum, sum / count); 15}

投稿2018/08/09 11:46

編集2018/08/09 11:59
asm

総合スコア15147

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

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

cateye

2018/08/09 12:09

すみません不勉強で申し訳ないのですが、 "%f%n"の%nはどういった変換なのでしょう?
asm

2018/08/09 12:20

scanf系関数によって読み取られた文字数です。 https://msdn.microsoft.com/en-us/library/6ttkkkhh.aspx > Pointer to int, into which is stored number of characters successfully read from stream or buffer up to that point in current call to scanf functions or wscanf functions. https://linuxjm.osdn.jp/html/LDP_man-pages/man3/scanf.3.html > どんな入力も必要としない。 そのかわりに、 入力からここまで消費された文字数が次のポインターで指定された場所に 格納される。 このポインターは int へのポインターでなければならない。 変換を抑制するのであれば * 代入抑制文字を使って抑制することができるのだが、 この変換指定子は変換では「ない」。 C 言語の標準規格では「実行の完了時に返される代入の回数は %n 命令の実行では増加しない」となっているが、 正誤表の内容はこれと矛盾するようである。おそらく、 %n 変換が返り値に与える影響についてはどのような仮定もしないのが 賢明であろう。
cateye

2018/08/09 12:48

ありがとうございました。 「%n 変換が返り値に与える影響についてはどのような仮定もしないのが 賢明」が気になりますが、まぁ通常は考えなくてもいいようですね^^;
退会済みユーザー

退会済みユーザー

2018/08/10 01:59

すごい!解読します sscanfでできないとあきらめかけていました。 ありがとうございます
退会済みユーザー

退会済みユーザー

2018/08/10 02:10

whileの中の動きがいまいちわからないです
退会済みユーザー

退会済みユーザー

2018/08/10 02:16

「s+offset」なぜ足しているのか、「&f, &n」なぜ2つあるのか、「 offset += n;」なぜこの分が必要なのか、教えていただけると幸いです。
asm

2018/08/10 03:34

結論だけ言うと、scanfで読み取った文字数を次回のscanfから読み飛ばすためです。 > 「s+offset」なぜ足しているのか puts("12345"+3); 等とするとご理解いただけるかと思いますが、文字列へのポインタに加算すると加算した数だけ先頭位置がズレます。 つまり、s+offsetでoffset分だけ先頭をズラしています。 > 「&f, &n」なぜ2つあるのか フォーマット文字列が"%f%n"だからです。 %nは上述した通り、指定された先頭からその部分までの文字数を返します。 これにより、%fで何文字読み取ったかを獲得します。 > 「 offset += n;」なぜこの分が必要なのか scanfで読み取った文字数を次回のscanfから読み飛ばすために 次回、何文字ズラすかを計算しています。
退会済みユーザー

退会済みユーザー

2018/08/10 07:19

whileでループさせる理由は、12 34 45と3つ数字があったら3つの数字を処理するためですか?
asm

2018/08/10 07:20

そういうことです
guest

0

sscanfの返り値は打ち込んだ数じゃなくて、変換した数です
提示コードでは1しか帰りません
また、

n = sscanf(s,"%f",&x);

x はdoubleじゃないとだめです

投稿2018/08/09 04:21

y_waiwai

総合スコア87774

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

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

退会済みユーザー

退会済みユーザー

2018/08/09 04:25

そうなんですよ、1しか返ってこないんですよどうやったら変換した数分出るようになりますか?
y_waiwai

2018/08/09 04:30

そこでは1個しか変換してないんで、まずはたくさん変換するようにしよう n = sscanf(s,"%f %f %f %f",&x1,&x2,&x3,&x4);
退会済みユーザー

退会済みユーザー

2018/08/09 04:59 編集

やはりそうなりますか、となると任意の数の場合だとは難しいということですね
y_waiwai

2018/08/09 05:09

任意にするならforかなんかで繰り返し処理しよう
退会済みユーザー

退会済みユーザー

2018/08/09 05:35

最初forで回していたのですが抜けれなくてかつ配列の[0]の場所だけに毎回入れることになる つまりn = sscanf(~~~~~);では、きびしそうってことですかね?
y_waiwai

2018/08/09 05:39

それはコードがイモってことで。 sscanfでは無理ですね strtof とかstrtod とか
退会済みユーザー

退会済みユーザー

2018/08/10 06:00

xは、なぜdoubleじゃないといけないのですか?
y_waiwai

2018/08/10 06:23

ああ、scanfの場合は%f はfloatですね。間違ってました
退会済みユーザー

退会済みユーザー

2018/08/10 06:25

回答ありがとうございます
guest

0

別解答です・・・

c

1usr~/test/c % cat ct0.c 2#include <stdio.h> 3#include <stdlib.h> 4// 5double Mean(void); 6 7int main(void) 8{ 9 printf("平均値=%lf\n",Mean()); 10 // 11 return 0; 12} 13// 14double Mean(void) 15{ 16 double sum= 0.0; 17 // 18 int cnt= 0; 19 char buf[64]; 20 // 21 while(fgets(buf,sizeof buf,stdin) != NULL){ 22 double in= strtod(buf,NULL); 23 if( in != 0.0 ){ 24 sum += in; 25 cnt++; 26 } 27 } 28 // 29 return sum / cnt; 30} 31// 32 33usr~/test/c % ./a.out 341.1 351.2 361.3 371.4 38平均値=1.250000 39usr~/test/c % ./a.out 400.2 410.2 42abc 430.3 440.3 45平均値=0.250000 46usr~/test/c %

投稿2018/08/09 15:59

cateye

総合スコア6851

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問