2011-09-01 51 views
2

我正在为学校编写一个程序,用户输入姓名,工作时间和小时工资。fgets()跳过

int main() 
{ 
    char name[SIZE]; 
    char selection = 'Z'; 
    int hoursWorked = 0, 
     counter = 0, 
     flag = 1; 
    float hourlyRate = 0.0; 
    const float otRate = 1.5; 
    const int week = 40; 

    while (flag == 1) 
    { 
     system ("cls"); 
     printf ("\n\tP A Y R O L L P R O G R A M\n"); 
     printf ("---------------------------------------------\n"); 
     printf ("\t(A) - New Payroll Info\n\t(B) - Display Payroll\n\t(C) - Quit\n\t"); 
     scanf (" %c", &selection); 
     selection = toupper (selection); 
     switch (selection) 
     { 
     case 'A': 
      system ("cls"); 
      printf ("Enter Employee Name: "); 
      fgets (name, SIZE, stdin); 
      strip_newline(name, 50); 
      printf ("\nEnter Hourly Rate: "); 
      scanf ("%f", &hourlyRate); 
      printf ("\nEnter Hours Worked This Week: "); 
      scanf ("%d", &hoursWorked); 
      system ("pause"); 
      break; 

大小为50,stdio.h中& stdlib.h中都包括在内。当我编译并移动到A开关时,它将跳过fgets()输入并直接进入"Enter Hourly Rate: "scanf()。我试图改变这个命令,把scanf()放在fgets()的前面,但是没有用。

+2

阅读[c-faq](http://c-faq.com/)的第12部分。而且,既然你已经在那里了,请阅读其他章节:-) – pmg

回答

4

您的scanf在输入缓冲区中留下一个换行符。因此,当调用fgets时,它会读取换行符并返回。

根据上面的pmg的注释,请查看C FAQ中的Question 12.18a的答案。

+1

我的回答是使用fflush(stdin)清除输入缓冲区 – Sean

+1

我会建议不要这样做。 'fflush(stdin)'具有未指定的行为......许多编译器会按照您的预期解释它,但有些编译器不会这样做,并且这可能会导致问题出现。我知道可携带性可能不是一个学校任务的关注点,但坏习惯的形成要比消除它更容易。 作为一种替代方案,我建议您使用您的scanf: –

+0

'scanf(“%c%* [^ \ n]”,&selection); assert('\ n'== getchar());'断言当然是可选的(但getchar()不是)。我只是想确定我正在吃换行符,而不是偶然的其他人物。我添加的%* [^ \ n]基本上是说“匹配不是换行符的所有内容”([^ \ n]模式)“但不要将它赋值给任何变量”(这就是*所做的)。 –

3

scanf可能是因为没有吃到行尾的回报,所以它被传递给第一个fgets。就个人而言,我讨厌scanf - 最好使用fgets,然后使用sscanf解析这行。

+0

但是在数字数据上使用sscanf时要小心;其溢出行为(例如,使用输入值超过INT_MAX的“%d”)未定义。 –

+0

@保罗汤姆林 - 哦,我记得那个名字上面有很多非常有趣的a.s.r引号。你先生是一个传奇:) –

+0

谢谢,@汤姆。我仍然在附近,只是不常见。 –