scanf异常与%c和%s相关的行为

时间:2014-01-04 01:57:46

标签: c stdin scanf

我想使用scanf来扫描std输入以获取字符以及字符串选项yes或no但是上面的代码跳过scanf(“%c”,& elem)并直接在scanf中获取字符串(“ %s“,选项)行。请建议一个很好的来源来解决这个问题。

 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);
    }

输出>>

  
    

./出     输入元素

  
a
you have entered a
enqueue elem= a
please enter yes or no yes
enter the elements

you have entered

enqueue elem=

3 个答案:

答案 0 :(得分:0)

当您按 Enter / 返回键输入元素时,\n字符也会与元素一起传递到缓冲区。下次通话时,\n会读取此getchar

要使用此\n,请将此行放在getchar();

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

答案 1 :(得分:0)

你的代码中没有任何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. 上找到它的样本
  3. 在读取输入后始终刷新输入缓冲区以防止出现类似问题。
  4. 输入函数检查输入缓冲区,您可以在0xb8000000找到它,并检查那里的第一个输入。如果缓冲区为空,则等待用户输入输入,否则,它们检查缓冲区中的第一个元素,然后检查它们预期读取的内容。如果它们成功,他们会读取它并将其从缓冲区中删除。否则,它们无法提供您的输入,并且根据功能,结果会有所不同。

    例如,请考虑以下行:

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

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

答案 2 :(得分: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);