用getchar()过量填充缓冲区后,C printf打印两次

时间:2017-03-18 20:57:54

标签: c printf 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字符太多时,它会urllib.read行两次,并在下一行打印其余部分。

我的问题是:为什么?

修改: 答案是好的,但有人在评论中指出输出是乱序的。为什么循环跳过printf()?

(我也不是本地人,对于糟糕的英语很抱歉)

4 个答案:

答案 0 :(得分:1)

您的代码示例中出现双重打印的原因已得到解答。要改进处理用户输入的方式,请考虑使用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.

答案 1 :(得分:1)

  

当我用太多字符溢出getchar()时,它会执行两次printf行并在下一行打印其余部分。   我的问题是:为什么会这样?

当您只读取输入的一部分时,其余字符仍然在输入流中。因此,当外循环继续时,getchar()将剩余的字符读入name

使用fgets()通常是更好的选择,但“额外”输入仍然存在同样的问题。

您可以使用一个简单的循环来消耗输入中可能存在的任何额外字符(在内部while循环之后):

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

答案 2 :(得分:0)

您正在通过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

}

答案 3 :(得分:0)

您的问题的答案很简单:while循环始终为true,因此当您输入超过24个字符的名称时,您的程序只扫描最多24个字符,然后打印名称并开始下一个循环。由于存在未在前一循环中扫描的字符,因此它们在流循环中被扫描。由于现有字符,程序不会要求输入。

如果你调试程序,你可以清楚地看到发生了什么。