2016-05-27 7 views
1

stdinからの入力を処理しようとしていますが、壁にぶち当たっています。 私の目標は数字の数字(0〜99)を読んで、それぞれを単語で印刷することです。 私の最初の試みでした:整数の不明な数を読み取り、それらを単語で印刷する

int main(void) { 

char *a[20] = {"zero","one","two","three","four","five","six","seven","eight", 
"nine","ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen", 
"seventeen","eighteen","nineteen"}; 

char *b[8] = {"twenty","thirty","fourty","fifty","sixty","seventy","eighty","ninety"}; 

int num=0, tens=0, ones=0; 

while (scanf("%d", &num)==1){ 
    tens = num/10; 
    ones = num%10; 

    if (tens>1){ 

     printf("%s ", b[tens-2]); 
     printf("%s \n", a[ones]); 
    } 
    else 
     printf("%s \n", a[num]); 
} 
printf("done"); 
return 0; 
} 

出力は正しいですが、scanf関数は、ループを終了することはありません。

第二の試み:ここ

int main(void) { 

char *a[20] = {"zero","one","two","three","four","five","six","seven","eight", 
"nine","ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen", 
"seventeen","eighteen","nineteen"}; 

char *b[8] = {"twenty","thirty","fourty","fifty","sixty","seventy","eighty","ninety"}; 
char line[1024], *ptr = NULL; 
long num; 
int tens=0, ones=0; 

if(fgets(line, sizeof(line), stdin)!=NULL){ 


    do { 
     num = strtol(line, &ptr, 10); 
     tens = num/10; 
     ones = num%10; 

     if (tens>1){ 

      printf("%s ", b[tens-2]); 
      printf("%s \n", a[ones]); 
     } 
     else 
      printf("%s \n", a[num]); 
    }while (*ptr!= '\n'); 
} 

printf("done"); 
return 0; 
} 

私はコンパイルエラーを取得し、それが動作するかどうか私にはわからないので、問題を見つけることができません。

[UPDATE]:2番目のコードは実行されますが、 12 35 51のように1つ以上の数字を入力すると無限に最初の数字(12文字)が印刷されます。

ご協力いただければ幸いです。

+0

コンパイルエラーは何ですか? –

+0

idが1の終了ステータスを返しました。 –

+0

何ですか?コンパイルエラーではありません。 –

答えて

1

あなたはとても近いです。 strtolの戻り値を確認し、strtolの呼び出しに続いてendptrに基づいてポインタアドレスを更新するだけです。また、ディスカッションで述べたように、コンバージョンの範囲外の値もチェックする必要があります。これは、すべてのことが必要とされている。

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 

int main(void) { 

    char *a[] = {"zero","one","two","three","four","five","six", 
       "seven","eight","nine","ten","eleven","twelve", 
       "thirteen","fourteen","fifteen","sixteen", 
       "seventeen","eighteen","nineteen"}; 

    char *b[] = {"twenty","thirty","fourty","fifty","sixty", 
       "seventy","eighty","ninety"}; 
    char line[1024] = ""; 
    long num; 
    int tens=0, ones=0; 

    if (fgets (line, sizeof(line), stdin) != NULL) { 

     char *p = line, *ep = NULL; 
     errno = 0; 

     while (errno == 0) { 
      num = strtol (p, &ep, 10);  /* convert to long */ 
      if (p == ep) break;    /* no digits, break */ 
      p = ep;       /* update p to ep */ 
      if (num < 0 || 99 < num) {  /* validate range */ 
       fprintf (stderr, "error: %ld - out of range.\n", num); 
       continue; 
      } 
      tens = num/10; 
      ones = num%10; 
      if (tens > 1) { 
       printf ("%s ", b[tens-2]); 
       printf ("%s \n", a[ones]); 
      } 
      else 
       printf("%s \n", a[num]); 
     } 
    } 

    printf ("done\n"); 

    return 0; 
} 

使用例/出力

$ ./bin/n2string 
12 55 61 -1 33 102 4 
twelve 
fifty five 
sixty one 
error: -1 - out of range. 
thirty three 
error: 102 - out of range. 
four 
done 

以上、それを見て、ご質問があれば私に知らせてください。

+0

ありがとうございました。私が完全に理解していないこと、なぜ別のポインタを使う必要があるのか​​、 "p"と "line"の両方が文字列の先頭を指していないのでしょうか? このコードを書く際に、strtolの最初のパラメータとして行を使用したいくつかの例を次に示します。ループ内で複数回strtolを使用すると違うのですか?基本的にこのコードの実行中に "p" "ptr"と "line"が初期値からどのように変化するか –

+0

'strtol'のために2番目のポインタが必要です。 * man strtol *を見ると、その宣言は 'long int strtol(const char * nptr、char ** endptr、int base);' 'nptr'が変換される文字列を指し、' endptr'が更新されます*変換後の最初の位置*に変換します(変換が行われる場合)。行ごとに1つ以上の数値を変換するには、最初に変換した後、 '(nptr!= endptr)'をチェックして変換が行われるようにしてから、 'nptr = endptr'(' p = ep') )あなたが変換した番号の後の*文字を指しているので、次の文字に変換することができます。 –

0

コードの目的は、入力された数字のテキスト版を印刷することです。あなたのコードはほとんど変わりません。ライブラリを追加して実行しました。

#include <stdio.h> 
#include <stdlib.h> 

int main(void) { 

    char *a[20] = {"zero","one","two","three","four","five","six","seven","eight", 
        "nine","ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen", 
        "seventeen","eighteen","nineteen"}; 

    char *b[8] = {"twenty","thirty","fourty","fifty","sixty","seventy","eighty","ninety"}; 
    char line[1024], *ptr = NULL; 
    long num; 
    int tens=0, ones=0; 

    if(fgets(line, sizeof(line), stdin)!=NULL){ 


     do { 
      num = strtol(line, &ptr, 10); 
      tens = num/10; 
      ones = num%10; 

      if (tens>1){ 

       printf("%s ", b[tens-2]); 
       printf("%s \n", a[ones]); 
      } 
      else 
       printf("%s \n", a[num]); 
     }while (*ptr!= '\n'); 
    } 

    printf("done"); 
    return 0; 
} 

テスト

19 
nineteen 
done 

たぶん、問題は、コードの目的を知らなかったということでした。

+0

私はそのコードを書いてその目的を知っているので、次のような数字を入力してみてください:12 25 58 ループは12を無限に印刷します 文字列の次の数字が入力から取り込まれているようです –

関連する問題