具有%c和%s相关行为的扫描异常

问题描述 投票:-1回答:3

我需要使用scanf来获取将存储用户答案的​​字符和字符串。 (是/否)下面的代码跳过scanf("%c", &elem)

while ( !strcmp ("yes", option))
{
    printf("enter the elements \n\n");
    elem=getchar();
    printf("you have entered %c\n",elem);
    enqueue(st, elem);
    printf("please enter yes or no ");
    scanf("%s[^\n]",option);
}
./out
enter the elements
a
you have entered a
enqueue elem= a
please enter yes or no yes
enter the elements

you have entered

enqueue elem=
c scanf
3个回答
1
投票

您的代码中没有任何scanf(“%c”,&elem)...顺便说一句,问题出在scanf的输入上。当您通过scanf获得输入时,输入字符将保留在输入缓冲区中,第二轮您的getchar()函数将读取该输入字符。一种简单的解决方法是在scanf行后添加一个虚拟getchar:

while ( !strcmp ("yes",option))
{
        printf("enter the elements \n\n");
        elem=getchar();
        printf("you have entered %c\n",elem);
        enqueue(st,elem);
        printf("please enter yes or no ");
        scanf("%s[^\n]",option);
        getchar();
}

您可以在此处找到有关如何清除输入缓冲区的更多信息:How to clear input buffer in C?

我可以建议您考虑两件事:

  1. [为了只获取一个字符,我个人发现在Windows中使用getchgetche函数要容易得多,在与GCC兼容的环境中,它们的使用等效。您可以在线或在此行中找到它的样本[What is Equivalent to getch() & getche() in Linux?
  2. 在读取输入后始终刷新输入缓冲区,以防止发生任何类似的问题。

输入功能检查输入缓冲区,您可以在0xb8000000处找到它,并检查那里的第一个输入。如果缓冲区为空,则他们等待用户输入输入,否则,他们检查缓冲区中的第一个元素,然后检查其是否达到期望读取的内容。如果成功,则将其读取并从缓冲区中将其删除。否则,它们将无法为您提供输入,并且根据功能,结果会有所不同。

例如,考虑以下行:

scanf("%d %d %f", &a, &b &c);

并输入为:a 2 4scanf将返回0,这意味着它将读取零个输入,因此'a',2和4仍保留在缓冲区中。因此您的缓冲区看起来像:[a,2,4]。结果,如果您添加以下行:scanf(“%c”,&ch);scanf将尝试从缓冲区中获取字符,然后读取字符“ a”并将其放入变量ch中。因此它不会从用户那里得到任何输入。最后,您的缓冲区又有了2和4。


1
投票

当您按下Enter / Return键输入元素时,\n字符也将与元素一起传递到缓冲区。下次呼叫时,\n将读取此getchar

要使用此\n,请在getchar();之后放置此行

int ch;
while((ch = getchar()) != EOF && ch != '\n'); 

0
投票

注意混合scanf()格式说明符"%c""%s""%[]"

"%[^\n]"的正确用法:没有s。如果不想保存前导空格,请按" %[^\n]"

包含前导空格。
char option[100];
// scanf("%s[^\n]", option);
scanf(" %[^\n]", option);
// or better
scanf(" %99[^\n]", option);
// or pedantic
switch (scanf(" %99[^\n]", option)) {
   case EOF: HandleEOForIOError(); break;
   case 0: HandleNoData(); break;  // might not be possible here.
   case 1: HandleSuccess();

正确使用"%c"。如果不想保存前导空格,请像" %c"中那样包含前导空格。在OP的代码中可能就是这种情况,因此前面的输入Enter'\n'被使用。

char elem;
scanf(" %c", &elem);

正确使用"%s"。前导空格不包含或不包含前导空格。

char option[100];
scanf("%99s", option);
// Following works the same.
scanf(" %99s", option);
© www.soinside.com 2019 - 2024. All rights reserved.