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

您的代码中只有两个小错误。

第一的,

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

应该

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

这就是它接受非整数的原因。另一件事是,stdin如果出现错误,您必须刷新scanf才能读取新内容:

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

把它放到你的程序中,它就可以工作了。

编辑:正如 Grijesh 指出的那样,fflush(stdin)不应该使用,所以你必须对重复的scanf. 其他人给出了一些可能性,但我留下了这个答案,因为它指出了你原来的逻辑错误。

于 2013-09-12T12:47:01.073 回答
0

如果scanf 遇到错误,这意味着即使您再次调用scanf,解析错误仍然存​​在,即它再次解析旧用户输入并且不接受新用户输入。

AFAIK,不可能使用 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

你只需要这个:

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 回答