簡體   English   中英

C printf用getchar()溢出緩沖區后打印兩次

[英]C printf prints two times after overfilling buffer with getchar()

我需要以下簡單代碼的幫助:

#include <stdlib.h>
#include <stdio.h>

int main() {
    system("clear");
    while (1) {
        printf("Enter your name(MAX 24 chars) : ");
        char name[25];
        int x = 0;
        do {
            name[x] = getchar();
            x++;
        } while (x != 24 && !(name[x - 1] == '\n'));

        name[x - 1] = '\0';
        printf("Well it looks like your name is : %s\n", name);
    }
}

它可以工作,但是卻做了一件奇怪的事情:

Enter your name(MAX 24 chars) : 123456789012345678901234567890
Well it looks like your name is : 12345678901234567890123
Well it looks like your name is : 567890
Enter your name(MAX 24 chars) : 

當我用太多字符過度填充getchar() ,它將執行兩次printf行,並將其余部分打印在下一行中。

我的問題是:為什么?

編輯 :答案很好,但有人在注釋中指出輸出不正常。 為什么循環跳過printf()?

(我也不是本地人,對英語不好對不起)

您的代碼示例中出現兩次重復打印的原因已得到解答。 為了改善處理用戶輸入的方式,請考慮結合使用fgets和sscanf來讀取用戶輸入:

    char name[25]; 
    char c[25]; 

    printf("Enter your name(MAX 24 chars) : ");
    fgets(c, sizeof(c), stdin);//reads string input from stdin. into c, 
                               //including newline char.
    sscanf(c, "%s", name);//string 'c' is evaluated and parsed into 'name'.
                          //The %s format specifier, when used in sscanf,
                          //consumes white space, such as \n.

當我用太多字符過度填充getchar()時,它將執行兩次printf行,並將其余部分打印在下一行中。 我的問題是:為什么?

當您僅讀取輸入的一部分時,其余字符仍在輸入流中。 因此,當外部循環繼續時, getchar()剩余的char讀入name

使用fgets()通常是更好的選擇,但“額外”輸入仍然會遇到相同的問題。

您可以使用一個簡單的循環來消耗輸入中可能存在的任何其他字符(在內部while循環之后):

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

您正在通過int x = 0重置數組,因此它正在重新打印,並且是一個無限循環。 這里是解釋:

while(1){ // enter infinite loop 2nd time
    printf("Enter your name(MAX 24 chars) : ");
    char name[25]; //declare new array 2nd declaration
    int x=0;    //reset of loop counter 2nd reset
    do{
        name[x] = getchar();    // start reading 2nd time read from the stream
        x++;
    }while(x!=24 && !(name[x-1] == '\n'));   // stop reading but data is
                                             //in stream

    name[x-1] = '\0';   // end of string marker
    printf("Well it looks like your name is : %s\n",name); // print and
                                                //enter loop again

}

您的問題的答案很簡單:while循環始終為真,因此當您輸入的名稱超過24個字符時,程序最多僅掃描24個字符,然后輸出名稱並開始下一個循環。 由於存在在上一個循環中未掃描的字符,因此將在流循環中對其進行掃描。 該程序不會因為存在字符而要求輸入。

如果調試程序,則可以清楚地看到發生了什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM