猫でもわかるの問題より

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
宗一郎

猫でもわかるの問題より

#1

投稿記事 by 宗一郎 » 14年前

いつもお世話になっております。

猫でもわかるプログラムのサイトで、C言語を勉強しているのですが、
少しわからないところがあったので質問させていただきました。

第30章 超簡単統計プログラムを作ろう
http://www.kumei.ne.jp/c_lang/intro/no_30.htm
での最後の問題です。

問題をまとめると
①繰り返し入力できるようにする。
②リターンキーで入力を終了できるようにする。
③入力してリターンキーを押したデータを修正できるようにする。

この①はできたのですが、②,③がわかりません。

以下が①を追加してみたコードです。
②,③の解答だけでなく、こういう風にしたほうがいいよ ということなどもありましたら、
ご教授お願いします。

コード:

#include <stdio.h>
#include <math.h>
#include <string.h>

void toukei();

int main()
{
	char cont[] = "y";

	while(strcmp(cont, "y") == 0) {
		toukei();
		
		printf("\n続けますか? yes=y, no=n\n");
		printf("入力:");
		scanf("%s", cont);

		for(int i=1; i <= 50; i++) {
			putchar('-');
		}
		putchar('\n');
	}

	return 0;
}

void toukei()
{
	int n;
    double sum, xsum, av, sg, sd;
    char data[64];
    n = 1;
    sum = 0.0;
    xsum = 0.0;
    while(1) {
        printf("data[%3d]=", n++);
        scanf("%s", data);
        if (strcmp(data, "E") == 0)
            break;
            
        sum += atof(data);
        xsum += pow(atof(data), 2.0);
    }
    n -= 2;
    av = sum / n;
    sg = xsum / n - pow(av, 2.0);
    sd = sqrt(sg);
    printf("\nデータの個数=%d\n", n);
    printf("合計        =%f\n", sum);
    printf("平均        =%f\n", av);
    printf("平方和      =%f\n", xsum);
    printf("分散        =%f\n", sg);
    printf("標準偏差    =%f\n", sd);

	return;
}

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: 猫でもわかるの問題より

#2

投稿記事 by h2so5 » 14年前

こう言い換えれば分かりますでしょうか?

2) 何も入力せずにリターンキーを押した場合、入力を終了する。

3) (あくまで一例です)
R [任意の番号] を入力した場合、その番号のデータの入力画面になる。
例)R 4 と入力 → data[  4]= と表示され、入力ができる。

3の方法はいくらでも実装方法があると思いますので、これは参考程度にどうぞ。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 猫でもわかるの問題より

#3

投稿記事 by みけCAT » 14年前

toukei関数内の入力部分

コード:

        printf("data[%3d]=", n++);
        scanf("%s", data);
        if (strcmp(data, "E") == 0)
            break;

コード:

        printf("data[%3d]=", n++);
        fgets(data,sizeof(data),stdin);
        *strchr(data,'\n')=0;
        if (strlen(data) == 0)
            break;
にすれば2はできると思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

宗一郎

Re: 猫でもわかるの問題より

#4

投稿記事 by 宗一郎 » 14年前

h2so5さん みけCATさん
解答ありがとうございます。

とりあえず、h2so5さんの書かれたような考え方でやってみます。
できなかった場合、また質問するかもしれません。
そのときは、どうかよろしくお願いします。

宗一郎

Re: 猫でもわかるの問題より

#5

投稿記事 by 宗一郎 » 14年前

とりあえず、みけCATさんの書かれたように打ち直してみました。

ですが、リターンキーで終了することはできるようになりましたが、
yで続けようとすると、次のデータの個数が0個になってしまい、続けて入力することができなくなりました。

なにか解決策はないでしょうか?
ご教授お願いします。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 猫でもわかるの問題より

#6

投稿記事 by みけCAT » 14年前

main関数をこうしてみてください。

コード:

int main()
{
    char cont[] = "y";
    int a;
 
    while(strcmp(cont, "y") == 0) {
        toukei();
        
        printf("\n続けますか? yes=y, no=n\n");
        printf("入力:");
        scanf("%s", cont);
        while(1) {
            a=getchar();
            if(a==-1 || a=='\n')break;
        }
 
        for(int i=1; i <= 50; i++) {
            putchar('-');
        }
        putchar('\n');
    }
 
    return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

宗一郎

Re: 猫でもわかるの問題より

#7

投稿記事 by 宗一郎 » 14年前

みけCATさん
本当にありがとうございます。
ちゃんとなりました。

あと一つだけ申し訳ないのですが、
*strchr(data,'\n')=0;
の部分がいまいち理解できていないので、
よろしければ解説してもらえないでしょうか?

strchr関数を使っているので、\nを検索しているのはわかるのですが。
それに0を代入していることで、意味がわからなくなってしまいました。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 猫でもわかるの問題より

#8

投稿記事 by みけCAT » 14年前

まず、fgets関数を使うと、読み込んだ文字列の最後に改行が付きます。
その改行のところのポインタをstrchr関数で探し、そこに0を代入することにより改行を消しています。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

宗一郎

Re: 猫でもわかるの問題より

#9

投稿記事 by 宗一郎 » 14年前

みけCATさん
解説ありがとうございました。

みけCATさん、 h2so5さんのおかげで無事解決できました。

③に関しては、ひとつ前のデータだけですが、修正できるようになりました。
本当にありがとうございました。

フリオ

Re: 猫でもわかるの問題より

#10

投稿記事 by フリオ » 14年前

 既に解決になってますが、

>まず、fgets関数を使うと、読み込んだ文字列の最後に改行が付きます。
>その改行のところのポインタをstrchr関数で探し、そこに0を代入することにより改行を消しています。

 fgetsで読み込んだ文字列に必ず改行がつくとは限りません。
例えば、改行の前にEOFが見つかればそこで読み込みを止め、当然この場合は改行はつきません。

そして、strchrはターゲットとなる文字が見つからなければNULLを返すので、
この場合、NULLを参照して、0('\0')を代入することになります。

ですから、strchrの戻り値は一旦変数で受けてNULLかどうかの判定をすべきです。

閉鎖

“C言語何でも質問掲示板” へ戻る