2015-09-10 24 views
-4

我使用C玩,寫了這個代碼:得到()函數從第二次起跳過

1 #include<stdio.h> 
    2 #define ASK_PROMPT printf("\nDo you want to continue(Y/N):"); 
    3 main() 
    4 { 
    5 char main[20], i; 
    6 start: 
    7 printf("Please enter your string:\n"); 
    8 gets(main); 
    9 printf("\nstring entered was:\n \n%s\n", main); 
    10 ASK_PROMPT; 
    11 scanf("%c",&i); 
    12  
    13 if(i=='Y'||i=='y') 
    14  goto start; 
    15 getch(); 
    16 return; 
    17 } 
當我執行這個代碼

,該goto loop無法正常工作。在提供yY對第10行問題的回答時,循環確實起作用,並且第7行再次執行/打印,但第8行被跳過(不等待輸入提供)。

  • 任何人都可以解釋它爲什麼會發生?
  • 我該如何解決?
+1

此代碼應該是**不**的典型例子。 – Haris

+1

這幾乎是你爲了輸入「Y」或「Y」而擊中多個鍵。但是,這將是非常明顯的,所以你必須已經排除了在調試中的可能性... – EOF

+0

意味着,不應該使用goto?我通常不使用轉到。但我想問的是爲什麼它不要求輸入。程序是否忘記main已經被聲明瞭? (請不要介意「主」作爲另一件事,我試圖) – user2507780

回答

0

修復

變化scanf("%c",&i);scanf("%c%*c",&i);

問題

\n輸入i是什麼原因造成gets()不等待輸入後。使用gets()goto

良好做法

  • 停止相反,你可以使用fgets()scanf()等切勿使用廢棄的函數。
  • 更改charmain到的數組名稱。

感謝@Coolguy關於使用scanf的評論。

+0

感謝您的答覆和建議,但即使更改代碼後你的建議是顯示同樣的問題 – user2507780

+0

我已經在我的系統上試過了,然後發佈了答案,你在使用哪種編譯器? – vish4071

+1

@ user2507780使用'scanf(「%c%* c」,&i);' uld建議使用@ ameyCU的解決方案雖然 –

2

我建議使用gets如果輸入的字符串是比main[20]規模較大的有什麼用gets。而。 gets不會阻止這一點,它會導致UB

使用fgets -

fgets(main,20,stdin); 

和理性您的問題是,它仍然在stdin原因'\n'scanf("%c",&i);這是gets回報,因爲它遇到'\n'

爲了避免'\n'後就可以scanf語句做到這一點 -

int c; 
while ((c = getchar()) != EOF && c != '\n'); 
+0

感謝您的回覆,我根據您的建議進行了更改。在更改之後,字符串的第一個字母被刪除/截斷,問題依然存在。 – user2507780

+0

@ user2507780您是否按照我所說的添加了代碼? 'getchar'的行應該在'scanf('%c',&i);'在你的代碼中。 – ameyCU

+0

@CoolGuy啊我總是忘記它加null。謝謝!! :) – ameyCU

1

問題:

打字Ÿ響應您的提示下輸入之後,你的程序的輸入流中包含的字符'y''\n'(換行字符)。調用scanf將從輸入流中刪除'y'字符,並保留換行符。

gets從輸入流中讀取,直到它看到一個換行符,並丟棄它;因爲它看到的第一件事是來自上一個條目的換行符,它將返回而不讀取任何其他輸入。

解決辦法:

首先,不要使用gets。永遠。它在1999年修訂版中已被棄用,並已從2011年修訂版中完全刪除。使用它在您的程序中引入故障點/安全漏洞。取而代之的是撥打fgets,請注意fgets會嘗試將新行存儲在目標緩衝區(如果有空間的話)。

其次,您需要從輸入流中消耗尾隨的換行符。通過vish4071給出的答案顯示了一種方法 - 使用scanf閱讀下列您輸入的字符(這應該是換行符),並丟棄:

scanf(" %c%*c", &i); 

在格式字符串中的前導空白告訴scanf跳過任何前導空格,%c轉換說明符告訴scanf從輸入流讀取下一個字符並將其值存儲到i,並且%*c轉換說明符告訴scanf從輸入流讀取下一個字符並丟棄它。

另一種選擇是,直到你看到一個換行符消耗輸入:

scanf(" %c", &i); 
while (getchar() != '\n') // repeatedly read characters from input stream 
    ;       // until we see a newline 

另一個選擇是讀你的輸入作爲另一個字符串:

char answer[3]; // space for y/n response plus newline plus 0 terminator 
... 
if (fgets(answer, sizeof answer, stdin)) 
{ 
    if (tolower(answer[0]) == 'y') 
    { 
    // do stuff 
    } 
} 

你可能會想,以檢查在answer緩衝區中存在換行符;如果它不在那裏,那麼用戶鍵入的字符數大於緩衝區大小,這可能會使將來的讀取變得糟糕,並且在下一次讀取操作之前需要清除該虛假輸入:

if (!strchr(answer, '\n')) 
    while (getchar() != '\n') 
    ; 
0

對現有代碼的最小修復,只需第二次使用gets(main)。如果代碼要使用ASK_PROMPT ;,那麼ASK_PROMPT的定義不需要結尾; 。如前所述,您可以使用fgets()而不是gets(),並使用適當的循環代替start:並轉到。

#include<stdio.h> 
#define ASK_PROMPT printf("\nDo you want to continue(Y/N):") 
int main() 
{ 
    char main[20]; 
    start: 
    printf("Please enter your string:\n"); 
    gets(main); 
    printf("\nstring entered was:\n \n%s\n", main); 
    ASK_PROMPT; 
    gets(main); 
    if(main[0]=='Y'||main[0]=='y') 
     goto start; 
    getch(); 
    return(0); 
} 
相關問題