- 締切済み
コードのどこが間違っているのかを教えてください。
ある文字を入力し、それをカンマ区切りして3つに分け、その3つの最大値を表示するプログラムを入力したいです。ただし、条件として、上限の桁数5を越える、文字か数字化の判定を行い、文字が1つでも混ざっている際はエラー表記され再度入力、さらに終了判断を行う際も、あくまで「y」「n」と入力したときのみが正常であり、複数文字を入力する際は、エラー表記され、再度入力という形をとりたいです。 フローを書きながら、サブ関数も使い、LINUXで以下のように書いてみました。 ただ、これだと /*-----------------------------------------*/ /tmp/ccKMOmJN.o: In function `word_judge': kadai6.c:(.text+0x4b2): undefined reference to `isdigits' collect2: ld はステータス 1 で終了しました /*-----------------------------------------*/ となってしまいました。 どのようなコードに直せばいいのでしょうか? すごく長いですが、わかりやすく解説してくださると、とても助かります。 あと、fgets関数やsscanf、getchar関数など、ネット上のサンプルを参照して、使っただけなので、もしかしたら間違ってるかもしれません。 そこについても、教えてくださると、とてもうれしいです。 /* ソースコード */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <limits.h> #define LIMIT (5) #define NULLB '\0' #define ECOUNT (20) #define EWORD (2) int word_judge(char array[]); void digits_judge(int a_len , int b_len , int c_len) ; int main(int argc , char *argv[]) { int number_a ; int number_b ; int number_c ; int input_len ; int a_len ; int b_len ; int c_len ; int end_len ; char input[ECOUNT] ; char a[ECOUNT] ; char b[ECOUNT] ; char c[ECOUNT] ; char array[ECOUNT] ; char end[EWORD] ; end[0] = 'n' ; while( end[0] == 'n' ) { while(1) { number_a = 0 ; number_b = 0 ; number_c = 0 ; input_len = 0 ; a_len = 0 ; b_len = 0 ; c_len = 0 ; end_len = 0 ; memset(input , NULLB , sizeof(char) *ECOUNT) ; memset(a , NULLB , sizeof(char) *ECOUNT) ; memset(b , NULLB , sizeof(char) *ECOUNT) ; memset(c , NULLB , sizeof(char) *ECOUNT) ; memset(end , NULLB , sizeof(char) *EWORD) ; printf("a , b , c ?:") ; fgets(input , ECOUNT , stdin); input_len = strlen(input); if( input_len < ECOUNT-1 ) { sscanf(input , "%[^,] , %[^,], %s" , a , b , c); if(a[0] != NULLB && a[0] != NULLB && c[0] != NULLB) { if(word_judge(a) != 0 && word_judge(b) != 0 && word_judge(c) != 0 ) { a_len = strlen(a) ; b_len = strlen(b) ; c_len = strlen(c) ; if(a_len >= LIMIT || b_len >= LIMIT || c_len >= LIMIT) { digits_judge(a_len , b_len , c_len) ; } else { number_a = strtol(a , NULL , 10) ; number_b = strtol(b , NULL , 10) ; number_c = strtol(c , NULL , 10) ; printf("最大値:") ; if(number_a > number_b && number_a > number_c) { printf("%d\n", a); } else { if(number_b >number_a && number_b > number_c) { printf("%d\n", b) ; } else { printf("%d\n", c) ; } } break ; } } else { printf("文字が混ざっています。\n") ; } } else { printf("正しく入力して下さい。\n") ; } } else { if(input[ECOUNT] == '\n') { } else { while(getchar() != '\n'); } printf("入力数が多いです。\n"); } } while(1) { int end_len ; char end[EWORD] ; end_len = 0 ; memset(end , NULLB , sizeof(char) *EWORD) ; printf("終了しますか? y/n: "); fgets(end , EWORD , stdin); end_len = strlen(end); printf("\n"); if(end_len == EWORD) { if(end[0] != 'y' && end[0] != 'n') { printf("y or nを入力して下さい。\n"); } else { break ; } } else { if(input[ECOUNT] == '\n') { } else { while(getchar() != '\n'); } printf("入力が間違っています。y or n を入力しなおしてください。\n"); } } } return 0 ; } int word_judge(char array[ ]) { int array_len ; int i ; int tmp ; int r_value ; tmp = 0; r_value = 0 ; for(i=0 ; i< array_len ; i++) { tmp = isdigits(array[i]) ; if(tmp != 0) { r_value = 1; } else { r_value = 0; break ; } } return r_value ; } void digits_judge(int a_len , int b_len , int c_len) { int a ; int b ; int c ; a = 0 ; b = 0 ; c = 0 ; a_len = 0 ; b_len = 0 ; c_len = 0 ; if(a_len >= LIMIT) { a = 1 ; } else { } if(b_len >= LIMIT) { b = 10 ; } else { } if(c_len >= LIMIT) { c = 100 ; } else { } switch(a + b + c) { case 111 : printf("aとbとcの桁が多いです。\n"); break; case 11 : printf("aとbの桁が多いです。\n"); break; case 110 : printf("bとcの桁が多いです。\n"); break; case 101 : printf("cとaの桁が多いです。\n"); break; case 1 : printf("aの桁が多いです。\n"); break; case 10 : printf("bの桁が多いです。\n"); break; case 100 : printf("cの桁が多いです。\n"); break; } }
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- kb-nike
- ベストアンサー率36% (72/200)
一例としてどうぞ! //-------------------------------------------------------------------- #include <stdio.h> #include <string.h> #include <stdlib.h> #include <limits.h> #define LIMIT 5 #define ECOUNT 20 int word_judge(char array[]); void disp_max(char a[], char b[], char c[]); int main( int argc, char *argv[] ) { char input[ECOUNT]; char a[ECOUNT]; // 2次元配列を使いたいところだが… char b[ECOUNT]; char c[ECOUNT]; char *token; int ch; int flag; flag = 0; while(1){ if(flag > 0){ flag = 0; printf("終了: [y]、継続:[その他キー] ?:"); ch = fgetc(stdin); rewind(stdin); // 標準入力のクリア if(ch == 'y' || ch == 'Y') break; } printf("a, b, c ?:") ; fgets(input, ECOUNT, stdin); // ","を区切り子として分割する // 注意:strtok()第2引数には[,]と[スペース]を指定している if((token = strtok(input, ", ")) != NULL){ strcpy(a, token); if((token = strtok(NULL, ", ")) != NULL){ strcpy(b, token); if((token = strtok(NULL, ", ")) != NULL){ strcpy(c, token); } } } if(word_judge(a) < 1){ printf("Error: 文字列 a に数字以外の文字が含まれています!\n"); flag = 1; } if(word_judge(b) < 1){ printf("Error: 文字列 b に数字以外の文字が含まれています!\n"); flag = 1; } if(word_judge(b) < 1){ printf("Error: 文字列 c に数字以外の文字が含まれています!\n"); flag = 1; } if(flag > 0) continue; // 桁数のチェック if(strlen(a) > LIMIT){ printf("Error: 数字列 a の桁数が大き過ぎます!\n"); flag = 1; } if(strlen(b) > LIMIT){ printf("Error: 数字列 b の桁数が大き過ぎます!\n"); flag = 1; } if(strlen(c) > LIMIT){ printf("Error: 数字列 c の桁数が大き過ぎます!\n"); flag = 1; } if(flag > 0) continue; disp_max(a, b, c); break; } // while-end return 0; } // 文字列に数字以外を含むか? int word_judge(char array[]) { int i, n; for(i=0; i<strlen(array); i++){ if(! isdigit(array[i])) return 0; //数字以外を含む } return 1; // 数字以外を含まない } // 3個の数字列の表す整数値の最大値を表示する void disp_max(char a[], char b[], char c[]) { long max; long na, nb, nc; char **ptr = NULL; na = strtol(a, ptr, 10); nb = strtol(b, ptr, 10); nc = strtol(c, ptr, 10); max = na; if(max < nb) max = nb; if(max < nc) max = nc; printf("最大値: %ld\n", max); }
- Tacosan
- ベストアンサー率23% (3656/15482)
「サブ関数void digits_judge(int a_len , int b_len , int c_len) の部分のエラー表記がされません。」 はもちろんその関数がおかしいから. じっと見ればおかしいことがわかりますよ. ああ, word_judge もおかしいな. あと余談だけどいくつか突っ込んでおく: ・if 文で「条件を満たさないときには何もしない」なら else 以降は書かなくていいだろう. ・word_judge とか digits_judge では意味不明なのでもっと適した名前を付けること. 判定した結果どうであるのかを考えて名前を付けること. また, どちらも「xxxx_judge」という名前であるにもかかわらず一方が真理値を返すのに他方が何も返さないというのはバランスがおかしい. ・strtol を適切に使えば word_judge はそもそも不要. ・memset(input , NULLB , sizeof(char) *ECOUNT) ; などは memset(input, NULLB, sizeof input); などとする方が間違いにくくてより適切.
- nmktksk
- ベストアンサー率36% (75/208)
括弧を確認してください。 現在だとend_lenがEWORDじゃなければ printf("入力が間違っています。y or n を入力しなおしてください。\n"); が実行されています。
- ky072
- ベストアンサー率60% (85/140)
isdigits → isdigit ではないでしょうか。
補足
追加です。 エラーは表示されなくなりました。早速のご回答、ありがとうございます。 ただ、処理を行うと以下の問題が発生してしまいました。 文字列を正常に入力しなかった場合に、 「正しく入力して下さい」 「文字が混ざっています」 「入力数が多いです」 しかエラー表記されず、 サブ関数void digits_judge(int a_len , int b_len , int c_len) の部分のエラー表記がされません。 また、終了判断を行う際、 「y」入力の時はそのまま終了、 「n」入力の時は再度「a , b , c?」を入力、 「y n以外の文字(1つのみ)」入力の時は、「y or n を入力して下さい」、 「y n以外の文字(2つ以上)」のときは、「入力が間違っています。y or n を入力しなおしてください。」 となるべきなのに、 どれを入力しても、「入力が間違っています。y or n を入力しなおしてください。」と表示されてしまいます。 最大値が変な表示になっていたのは、 printf("%d\n", a) ; printf("%d\n", b) ; printf("%d\n", c) ; を printf("%d\n", number_a) ; printf("%d\n", number_b) ; printf("%d\n", number_c) ; にすれば解決出来たのですが、どうすれば解決できますか?