如何接受“;”分号,作为输入,而不是执行下一行代码?

时间:2017-10-29 05:30:47

标签: c scanf fgets

这是我正在做的一小部分练习,可以防止错误的输入。

while(1) {
        printf("Choose From 1 to 7 ");
        if( scanf("%d", &nNum ) != 1) { 
            printf("Please only choose from the numbers 1-7."); 
                fgets(sErraticInputs, 100 , stdin);
        } else if (nNum > 7 || nNum <= 0) {
            printf("Please only choose from the numbers 1-7.");
        } else {
            break;
        }
    }

我做得很好,直到我输入“6; p”。它执行了6部分并正确运行,但从技术上讲它应该将整个事情作为输入,然后继续输入错误消息。

2 个答案:

答案 0 :(得分:1)

首先,我不认为发布的代码可以提供上述结果。当break被读取时,while(1)语句将结束6,因此不会打印错误消息。

如果我们假设break不是您真实代码的一部分,则会发生以下情况:

当告诉scanf读取整数时,只要下一个字符(与先前读取的字符一起)可以转换为整数,它就会继续从输入流中读取。一旦下一个字符不能用作整数的一部分,scanf将停止并为您提供到目前为止已解析的结果。

在您的情况下,输入流包含

6;p\n

因此scanf会读取6并停止(即返回6)。输入流现在包含:

;p\n

因此,这将是您下一个scanf的输入,并导致输入错误,您看到了。

解决这个问题的一种方法是在所有 scanf之后刷新标准输入 - 无论是成功还是失败:

nNum = 0;
while(nNum != 7)  // Just as an example I use input 7 to terminate the loop
{
    printf("Choose From 1 to 7 ");
    if( scanf("%d", &nNum ) != 1 || nNum > 7 || nNum <= 0) 
    { 
        printf("Please only choose from the numbers 1-7."); 
    } 
    else 
    {
        printf("Valid input %d\n", nNum);
        // ****************************  break;  
    }
    fgets(sErraticInputs, 100 , stdin);  // Always empty stdin
}

注意:使用大小为100的fgets并不能确保完全刷新...您应该实际使用循环并继续直到读取'\n'

如上所述,6;p之类的输入将被视为值为6的有效输入,而p将被丢弃。

如果这不可接受,您可以放弃使用scanf并自行解析。有几种选择,例如fgetsfgetc

以下示例使用fgetc

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

int get_next()
{
    int in = fgetc(stdin);
    if (in == EOF) exit(1); // Input error
    return in;
}

void empty_stdin()
{
    while(get_next() != '\n') {};
}

int main(void) {
    int in;
    int nNum = 0;
    while(nNum != 7) 
    {
        printf("Choose From 1 to 7 \n");
        in = get_next();
        if (in == '\n' || in <= '0' || in > '7')  // First input must be 1..7
        {
            printf("Please only choose from the numbers 1-7.\n"); 
            if (in != '\n') empty_stdin();
        }
        else
        {
            nNum = in - '0';
            in = get_next();
            if (in != '\n')    // Second input must be \n
            {
                printf("Please only choose from the numbers 1-7.\n"); 
                empty_stdin();
            }
            else
            {
                printf("Valid input: %d\n", nNum);
            }
        }
    }   
    return 0;
}

此代码只接受一个数字(1..7)后跟换行符

答案 1 :(得分:0)

这就是&#34;整个事情&#34;不作为输入。从手册页:

  

格式字符串由一系列描述的指令组成   如何处理序列          输入字符。如果指令的处理失败,则不再读取输入,并且scanf()          回报。 A&#34;失败&#34;可以是以下任一项:输入失败,表示输入字符          不可用,或匹配失败,意味着输入不合适......

Here's全文。也请查看this

一种方法是使用fgets读入整个输入,并检查输入的长度是否大于1。对于长度为1的输入,请检查输入是否为数字,依此类推......