掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.25870

2回目のループにて入力が飛ばされてしまう
投稿者---HN(2006/01/31 15:57:53)


OS:WiNDOWSXP
コンパイラ:MicrosoftVisualC++


下記コードを実行すると1回目のループでは

面積を計算する種類を入力してください(0:三角形 1:台形 q=Exit):

で入力のため止まるのですが2回目以降は1回目に選択した種類のメッセージまでくっついて表示されてしまいます。

例えば1回目に入力した種類が0の場合なら

面積を計算する種類を入力してください(0:三角形 1:台形 q=Exit):底辺と高さを入力してください(スペースで区切る)

となってしまいます。いくら考えても理解出来ないので教えてください。

/*インクルードファイル*/
#include<stdio.h>

/*int→doubleに*/
#include<string.h>

#define int double
/*プロトタイプ宣言*/
int sannkaku(int teihen,int takasa);
int daikei(int joutei,int katei,int takasa);
/*メイン*/
int main(void){

/*最初に表示されるメッセージ*/
char* message="面積を計算する種類を入力してください(0:三角形 1:台形 q=Exit):";
/*入力を受け付ける時に使用する変数*/
char yes_or_no[10];
char input_syurui_char[100];
char input_sannkaku_char[100];
char input_daikei_char[100];
/*計算種類の選択に使う変数*/
int input_syurui_int;
/*三角形の計算に使う変数*/
int input_sannkaku_teihen;
int input_sannkaku_takasa;
int sannkaku_kekka;
/*台形の計算に使う変数*/
int input_daikei_joutei;
int input_daikei_katei;
int input_daikei_takasa;
int daikei_kekka;
FILE* fp;
/*ここから*/
while(1){
printf("%s",message);

/*種類の入力*/
fgets(input_syurui_char,sizeof(input_syurui_char),stdin);
sscanf(input_syurui_char,"%lf",&input_syurui_int);


/*入力された種類が0だった場合、底辺と高さを入力させ、引数をsannkaku関数に渡し、戻り値を表示する*/
if(input_syurui_int==0){

printf("底辺と高さを入力してください(スペースで区切る)");

fgets(input_sannkaku_char,sizeof(input_sannkaku_char),stdin);
sscanf(input_sannkaku_char,"%lf %lf",&input_sannkaku_teihen,&input_sannkaku_takasa);

sannkaku_kekka=sannkaku(input_sannkaku_teihen,input_sannkaku_takasa);

printf("種類 %2.0f の結果は %2.2f です\n\n",input_syurui_int,sannkaku_kekka);
/*ファイル出力*/
while(1){
printf("結果をファイルに出力しますか?(yes or no)");
scanf("%s",&yes_or_no);
if(strcmp(yes_or_no,"yes")==0){
fp=fopen("../結果.txt","w");
if(fp==NULL){
printf("異常です");
return 0;
}
fprintf(fp,"種類 %2.0f の結果は %2.2f です\n\n",input_syurui_int,sannkaku_kekka);
fclose(fp);
printf("出力しました\n\n");
break;
}else if(strcmp(yes_or_no,"no")==0){
break;
}else{
continue;
}
}

/*入力された種類が1だった場合、上底と下底、それから高さを入力させ、引数をsannkaku関数に渡し、戻り値を表示する*/
}else if(input_syurui_int==1){
printf("上底と下底、それから高さを入力してください(スペースで区切る)");
fgets(input_daikei_char,sizeof(input_daikei_char),stdin);
sscanf(input_daikei_char,"%lf %lf %lf",&input_daikei_joutei,&input_daikei_katei,&input_daikei_takasa);
daikei_kekka=daikei(input_daikei_joutei,input_daikei_katei,input_daikei_takasa);

printf("種類 %2f の結果は %2.2f です\n\n",input_syurui_int,daikei_kekka);
/*ファイル出力*/
while(1){
printf("結果をファイルに出力しますか?(yes or no)");
scanf("%s",&yes_or_no);
if(strcmp(yes_or_no,"yes")==0){
fp=fopen("../結果.txt","w");
if(fp==NULL){
printf("異常です");
return 0;
}
fprintf(fp,"種類 %2f の結果は %2.2f です\n\n",input_syurui_int,daikei_kekka);
fclose(fp);
printf("出力しました\n\n");
break;
}else if(strcmp(yes_or_no,"no")==0){
break;
}else{
continue;
}
}

/*種類にqが入力された場合、プログラムを終了する*/
}else if(*input_syurui_char=='q'){
break;
/*種類に怪しい入力を受け付けたらエラーを表示させ、最初からやり直し*/
}else{
printf("そんな種類ありません\n\n");
continue;
}
}
return 0;
}

/*三角形の計算関数*/
int sannkaku(int teihen,int takasa){

int modoriti;

modoriti=takasa*teihen/2;

return modoriti;
}

/*台形の計算関数*/
int daikei(int joutei,int katei,int takasa){
int modoriti;

modoriti=(joutei+katei)*takasa/2;

return modoriti;
}
</pre>

よろしくお願いします。


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:2回目のループにて入力が飛ばされてしまう 25871 Blue 2006/01/31 16:39:52
<子記事> Re:2回目のループにて入力が飛ばされてしまう 25874 REE 2006/01/31 16:53:03
<子記事> Re:2回目のループにて入力が飛ばされてしまう 25876 RiSK 2006/01/31 17:22:39


No.25871

Re:2回目のループにて入力が飛ばされてしまう
投稿者---Blue(2006/01/31 16:39:52)


とりあえず、HTML化に失敗していて見にく過ぎるので整形だけ。
投稿時には 「確認画面」でちゃんと表示されているか確認してください。

それと、長いソースをだらだら載せられても困りますので、ある程度デバッグをして怪しいところを絞って質問してください。
(VisualC++ならば良いデバッガがついていますし。)


/*インクルードファイル*/
#include<stdio.h>

/*int→doubleに*/
#include<string.h>

#define int double
/*プロトタイプ宣言*/
int sannkaku(int teihen,int takasa);
int daikei(int joutei,int katei,int takasa);
/*メイン*/
int main(void){

    /*最初に表示されるメッセージ*/
    char* message="面積を計算する種類を入力してください(0:三角形 1:台形 q=Exit):";
    /*入力を受け付ける時に使用する変数*/
    char yes_or_no[10];
    char input_syurui_char[100];
    char input_sannkaku_char[100];
    char input_daikei_char[100];
    /*計算種類の選択に使う変数*/
    int input_syurui_int;
    /*三角形の計算に使う変数*/
    int input_sannkaku_teihen;
    int input_sannkaku_takasa;
    int sannkaku_kekka;
    /*台形の計算に使う変数*/
    int input_daikei_joutei;
    int input_daikei_katei;
    int input_daikei_takasa;
    int daikei_kekka;
    FILE* fp;
    /*ここから*/
    while(1){
        printf("%s",message);

        /*種類の入力*/
        fgets(input_syurui_char,sizeof(input_syurui_char),stdin);
        sscanf(input_syurui_char,"%lf",&input_syurui_int);


        /*入力された種類が0だった場合、底辺と高さを入力させ、引数をsannkaku関数に渡し、戻り値を表示する*/
        if(input_syurui_int==0){

            printf("底辺と高さを入力してください(スペースで区切る)");

            fgets(input_sannkaku_char,sizeof(input_sannkaku_char),stdin);
            sscanf(input_sannkaku_char,"%lf %lf",&input_sannkaku_teihen,&input_sannkaku_takasa);

            sannkaku_kekka=sannkaku(input_sannkaku_teihen,input_sannkaku_takasa);

            printf("種類 %2.0f の結果は %2.2f です\n\n",input_syurui_int,sannkaku_kekka);
            /*ファイル出力*/
            while(1){
                printf("結果をファイルに出力しますか?(yes or no)");
                scanf("%s",&yes_or_no);
                if(strcmp(yes_or_no,"yes")==0){
                    fp=fopen("../結果.txt","w");
                    if(fp==NULL){
                        printf("異常です");
                        return 0;
                    }
                    fprintf(fp,"種類 %2.0f の結果は %2.2f です\n\n",input_syurui_int,sannkaku_kekka);
                    fclose(fp);
                    printf("出力しました\n\n");
                    break;
                }else if(strcmp(yes_or_no,"no")==0){
                    break;
                }else{
                    continue;
                }
            }

        /*入力された種類が1だった場合、上底と下底、それから高さを入力させ、引数をsannkaku関数に渡し、戻り値を表示する*/
        }else if(input_syurui_int==1){
            printf("上底と下底、それから高さを入力してください(スペースで区切る)");
            fgets(input_daikei_char,sizeof(input_daikei_char),stdin);
            sscanf(input_daikei_char,"%lf %lf %lf",&input_daikei_joutei,&input_daikei_katei,&input_daikei_takasa);
            daikei_kekka=daikei(input_daikei_joutei,input_daikei_katei,input_daikei_takasa);

            printf("種類 %2f の結果は %2.2f です\n\n",input_syurui_int,daikei_kekka);
            /*ファイル出力*/
            while(1){
                printf("結果をファイルに出力しますか?(yes or no)");
                scanf("%s",&yes_or_no);
                if(strcmp(yes_or_no,"yes")==0){
                    fp=fopen("../結果.txt","w");
                    if(fp==NULL){
                        printf("異常です");
                        return 0;
                    }
                    fprintf(fp,"種類 %2f の結果は %2.2f です\n\n",input_syurui_int,daikei_kekka);
                    fclose(fp);
                    printf("出力しました\n\n");
                    break;
                }else if(strcmp(yes_or_no,"no")==0){
                    break;
                }else{
                    continue;
                }
            }
        
        /*種類にqが入力された場合、プログラムを終了する*/
        }else if(*input_syurui_char=='q'){
            break;
        /*種類に怪しい入力を受け付けたらエラーを表示させ、最初からやり直し*/
        }else{
            printf("そんな種類ありません\n\n");
            continue;
        }
    }
return 0;
}

/*三角形の計算関数*/
int sannkaku(int teihen,int takasa){

    int modoriti;

    modoriti=takasa*teihen/2;

    return modoriti;
}

/*台形の計算関数*/
int daikei(int joutei,int katei,int takasa){
    int modoriti;

    modoriti=(joutei+katei)*takasa/2;

    return modoriti;
}

# 色付けしようかと思ったけど、あまりにソースが長すぎて、文字数エラーになってしまった。



この投稿にコメントする

削除パスワード

No.25873

Re:2回目のループにて入力が飛ばされてしまう
投稿者---Blue(2006/01/31 16:51:57)


もしかして
5−4.scanf()の注意事項 (2)改行文字が残る
かな?

なんで他のところは fgets + sscanf なのに
>                printf("結果をファイルに出力しますか?(yes or no)");
>                scanf("%s",&yes_or_no);
だけ scanf なんだろうか?

もう少し、処理を関数化してみるとすっきりしたコードがかけます。



この投稿にコメントする

削除パスワード

No.25874

Re:2回目のループにて入力が飛ばされてしまう
投稿者---REE(2006/01/31 16:53:03)


>で入力のため止まるのですが2回目以降は1回目に選択した種類のメッセージまでくっついて表示されてしまいます。

定番のこれですね。
http://www9.plala.or.jp/sgwr-t/c/sec05.html#s5-4



この投稿にコメントする

削除パスワード

No.25876

Re:2回目のループにて入力が飛ばされてしまう
投稿者---RiSK(2006/01/31 17:22:39)


デバッグの仕方を覚えましょう。
が、その前に、デバッグをしにくくするコーディングもやめましょう。
本題については他の方が指摘していますので、私はこの点を。

  1. #define int double なんて恐ろしいことをしないでください。

     doubleが欲しいのならdoubleと宣言すべきです。
     型を切り替える必要があるなら、
     #define MY_TYPE double とでもして、MY_TYPE を使えば、
     後で型を変更しやすいです。(*1)

     (*1) ただしprintfやsscanfの可変長引数では型チェックがされないので注意。


  2. mainが長すぎます。しかも変数がmainの最上位ブロックにたくさんあります。
     これではグローバル変数と対して変わりません。

     変数宣言を全部コメントアウトしコンパイルします。
     エラーが出たら関連する(コメントアウトした)宣言を
     エラーが出た行のブロック(*2)に移動します。
     それでもエラーが出たら一つ階層が浅いブロックに移動します。
     エラーが減るまで繰り返します。
     コメントアウトした宣言がなくなるまで繰り返します。

     (*2) C99に対応していない場合はブロックの先頭で宣言する必要があります。


  3. 同じような処理が複数回出ています。これでは仮に片方を修正したとしても
     もう片方を修正し忘れる可能性も出てきます。

     関数化すると良いです。


これらを実践(=書き直し)するだけで自然とバグがなくなることも多いです。



この投稿にコメントする

削除パスワード

No.25904

Re:2回目のループにて入力が飛ばされてしまう
投稿者---HN(2006/02/01 08:46:50)


効率的なプログラミング手法まで教えていただきありがとうございます。
助かりました。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧