2011-09-01 52 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

謝謝,@湯姆。我仍然在附近,只是不常見。 –