0

When compiling to Linux with gcc, everytime the user inputs whatever answer, the program reaches the same part of the code in other iteration but doesn't waits for the input of the user, and instead feeds a newline to the scanf function, making the program print 'I don't get it!' every time... The program works, but still, I didn't want it to write 'I don't get it!', independent of the users' answer. Here's the specific part of the code.

do
{
    printf("\n\nAnswer: (y/n) ");
    scanf("%c", &ans);
    //printf("\n->%c<-\n", ans); //just for debugging
    if (ans == 'y')
    {
        age += v[0];
    }
    else if (ans != 'n')
    {
        printf("\nI don't get it!\n");
    }
} while (ans != 'y' && ans != 'n');

These are the declarations:
char v[64];
char ans;

(This do..while loop is inside a 'for') What further puzzles me is the fact that the program compiles and runs exactly as I'd expect on Windows... (using MinGW) I've tried using fflush(stdin) before and/or after the scanf, but it didn't help. An important observation is that the first time it reaches this question it acts as expected.

(before the user answers)
Answer: (y/n)
I don't get it! // this gets written every time but the first

Answer: (y/n) n

You are 21 years old!

If the user writes invalid input:

Answer: (y/n) w

I don't get it!

Answer: (y/n) // this line and the next one should simply not be printed
I don't get it!

Answer: (y/n)
//(now it waits for user input)

Any ideas?

Edit

Fixed it: (I declared an additional char buf[50])

do
{
    printf("\n\nAnswer: (y/n) ");
    fgets(buf, 50, stdin);
    sscanf(buf, " %c", &ans);
    if (ans == 'y')
    {
        age += v[0];
    }
    else if (ans != 'n')
    {
        printf("\nI don't get it!\n");
    }
} while (ans != 'y' && ans != 'n');

Can someone tell me what is the problem with scanf?

4

2 回答 2

1

停止使用scanf。现在。

改为使用fgets(buffer, BUFLEN, stdin)。然后用于sscanf解析结果。它会更健壮,它会摆脱你的问题。

我听说在格式说明符周围添加空格也有帮助,因为它消除了残留的“空白”。scanf(" %c", &ans);但我不喜欢它。

这里的更新是一段代码,我相信它的运行方式与您希望的一样(我用printf语句替换了内部,但您明白了;我还if用 a 替换了您的 s switch- 我认为它更清洁):

#include <stdio.h>
#include <string.h>

#define N 100

int main(void) {

  char buf[N];
  char ans;
  int ii;

  for (ii = 0; ii < 10; ii++)
  {
    do
    {
      printf("\n\nAnswer: (y/n) ");
      fgets(buf, N, stdin);
      sscanf(buf, "%c", &ans);
      printf("==%c==", ans);
      switch(ans)
      {
      case 'y':
        printf("\nYou said yes :-)\n");
        break;
      case 'n':
        printf("\nYou said no :-(\n");
        break;
      default:
        printf("\nI don't get it!\n");
      }
    } while (ans != 'y' && ans != 'n');
  }
}
于 2014-02-12T23:50:47.497 回答
0

按照@Floris 回答关于fgets()


如果必须使用scanf(),请使用

scanf(" %c", &ans);

前面的空格"%c"将消耗任何和所有前导空格,包括前一行的Enteror '\n'

一个人当然不想添加以下空格,因为这会导致scanf()消耗所有空格,直到输入另一个非空格。由于stdin通常是缓冲的,因此它们意味着需要 '\n'在非空白之后的附加空间才能将行提供给scanf().

于 2014-02-13T00:18:14.927 回答