5

ここでひどく明白な何かが欠けているように感じますが、コードの問題を見つけることができないようです. 入力が整数かどうかを調べるために scanf を使用しようとしています。整数でない場合は、ユーザーに再入力を求めるだけです。ただし、何らかの理由で、逆の場合、つまり整数が受け入れられず、それ以外は受け入れられない場合にのみ、コードを機能させることができるようです。修正するのは簡単な問題のようですが、それ以外の場合は無限ループが発生します。皆さんの助けをいただければ幸いです。

#include <stdio.h>
enum state {success,fail,quit};
int status = fail;

int main(void)
{
int n;
char t;
do
{
printf("Enter a number between 0 and 32767: ");

if(scanf("%d%c", &n, &t) != 2 )
status = success;
}
while (status == fail);
if (status == success)
{

int oct1, oct2, oct3, oct4, oct5;

oct1 = ((((n / 8) / 8) / 8) / 8) % 8;
oct2 = (((n / 8) / 8) / 8) % 8;
oct3 = ((n / 8) / 8) % 8;
oct4 = (n / 8) % 8;
oct5 = n % 8;

printf("In octal, your number is: %d%d%d%d%d\n", oct1, oct2, oct3, oct4, oct5);
return 0;
}
}
4

5 に答える 5

1

数値以外の値を入力すると、入力バッファーから削除されず、数値をスキャンしようとしている間ずっとそこにとどまるという問題があります。

代わりに、行を個別に読んでから、その行から番号を取得してみてください。このようなもの:

for (;;)
{
    printf("Enter a number: ");

    /* Get a line of input from the user */
    char line[128];
    if (fgets(line, sizeof(line), stdin) == NULL)
    {
        /* Error reading */
        perror("fgets");
        break;
    }

    /* The `fgets` function leaves the newline in the string */
    /* Remove it by overwriting it with the string terminator */
    line[strlen(line) - 1] = '\0';

    /* Convert to a number */
    char *endptr = NULL;
    n = strtol(line, &endptr, 10);

    /* Check if a valid number was entered */
    if (endptr == line)
        printf("Not a valid number, please enter again\n");
    else if (endptr < (line + strlen(line)))
        printf("Line begins with a number, but then there is garbage\n");
    else
        break;  /* We got a valid number */
}

可能性のあるガベージを気にしない場合は、sscanf代わりに使用して、これを次のように単純化できます。

for (;;)
{
    printf("Enter a number: ");

    /* Get a line of input from the user */
    char line[128];
    if (fgets(line, sizeof(line), stdin) == NULL)
    {
        /* Error reading */
        perror("fgets");
        break;
    }

    /* Try to get number as an unsigned short */
    if (sscanf(line, " %hu", &n) == 1)
        break;

    printf("Illegal number\n");
}
于 2013-09-12T11:37:57.633 に答える
1

コードをリファクタリングしました

#include <stdio.h>

    int main(void)
    {
    int n;
    char t;
    do
    {
    printf("Enter a number between 0 and 32767: ");
    scanf("%d", &n);
    }
    while( (n < 0) || (n > 32767)) ; //check the range of the input.if not there in this range then re read input.
    printf("In octal, your number is: %o \n", n); //print octal of input with %o format specifier.
    return 0;
    }
于 2013-09-12T11:40:47.310 に答える
0

必要なのはこれだけです:

do
{
   printf("Enter a number between 0 and 32767: ");

   if(scanf("%d", &n) == 1 && ((n > 0) && (n < 32767)) )
     status = success;
   else
     while((t=getchar()) !='\n' && t !=EOF) ; //Eat the trailing newline
}while (status == fail);

こちらをご覧ください

于 2013-09-12T11:41:08.467 に答える
0

scanf でエラーが発生した場合は、scanf を再度呼び出しても解析エラーがまだ存在することを意味します。つまり、古いユーザー入力を再度解析し、新しいユーザー入力を取得しません。

私の知る限り、scanfを使用して整数の解析でエラーを見つけることはできません。scanf("%s")/fgets() に続いて strtol などの他の適切な関数を使用します。

while (1)
{
    char input[128], *endptr;
    int value;
    scanf("%s", input);
    value = strtol(input, &endptr, 10);
    if (endptr != input)
    {
        break;
    }
    printf("input again\n");
}
于 2013-09-12T11:36:30.480 に答える
0

コードには 2 つの小さなエラーがあります。

初め、

if(scanf("%d%c", &n, &t) != 2 )
  status = success;

する必要があります

if(scanf("%d%c", &n, &t) == 2 )
  status = success;

それが非整数を受け入れた理由です。もう 1 つは、何か新しいものを読み取るstdinためにエラーが発生した場合は、フラッシュする必要があることです。scanf

if(scanf("%d%c", &n, &t) == 2 )
  status = success;
else
  fflush(stdin);

これをプログラムに入れると、機能します。

編集: Grijeshが指摘しているfflush(stdin)ように、使用すべきではないため、繰り返されるscanf. 他の人はいくつかの可能性を示しましたが、元の論理障害を指摘しているため、この回答を残します。

于 2013-09-12T12:47:01.073 に答える