繁体   English   中英

为什么不是scanf(“%* [^ \\ n] \\ n”); 和scanf(“%* [^ \\ n]%* c”); 清除挂起的换行符?

[英]Why aren't scanf(“%*[^\n]\n”); and scanf(“%*[^\n]%*c”); clearing a hanging newline?

在调用scanf("%d", &variable); 我们在stdin上留下了换行符,应该在调用fgets之前清除该换行符,否则我们最终将其换行,并使其过早返回。

我找到了建议使用scanf("%*[^\\n]%*c");答案scanf("%*[^\\n]%*c"); 在第一次调用scanf放弃换行符后,其他人建议使用scanf("%*[^\\n]\\n"); 从理论上讲,这两个应该工作:首先将消耗所有不换行(但不包括新行本身),然后消耗一个字符(新行)。 第二个将消耗掉所有不是换行符的内容(不包括换行符),然后\\n (一个空格字符)将指示scanf读取每个空格字符,直到第一个非空格字符为止。

但是,就我看来,这些方法在某些答案中可以起作用,但我无法在这里使它们起作用(下面的代码)。

为什么两种scanf方法都scanf

测试于:Ubuntu Linux- gcc 5.4.0

scanf("%*[^\\n]\\n"); 方法:

#include <stdio.h>

int main(int argc, char **argv){
    int number;
    char buffer[1024];

    printf("Write number: \n");
    scanf("%d", &number);

    //Clearing stdin?
    scanf("%*[^\n]\n");

    printf("Write phrase: \n");
    fgets(buffer, 1024, stdin);

    printf("\n\nYou wrote:%u and \"%s\"\n", number, buffer);

    return 0;
}

输出:

$ ./bug 
Write number: 
2
Write phrase: 


You wrote:2 and "
"

scanf("%*[^\\n]%*c"); 方法:

#include <stdio.h>

int main(int argc, char **argv){
    int number;
    char buffer[1024];

    printf("Write number: \n");
    scanf("%d", &number);

    //Clearing stdin?
    scanf("%*[^\n]%*c");

    printf("Write phrase: \n");
    fgets(buffer, 1024, stdin);

    printf("\n\nYou wrote:%u and \"%s\"\n", number, buffer);

    return 0;
}

输出:

$ ./bug2 
Write number: 
3
Write phrase: 


You wrote:3 and "
"

以下方法是唯一按预期方式工作的方法:

工作方法:

#include <stdio.h>

int main(int argc, char **argv){
    int number;
    char buffer[1024];

    printf("Write number: \n");
    scanf("%d", &number);

    //Clearing stdin!
    int c;
    while((c = getchar()) != '\n' && c != EOF){
        //Discard up to (and including) newline
    }

    printf("Write phrase: \n");
    fgets(buffer, 1024, stdin);

    printf("\n\nYou wrote:%u and \"%s\"\n", number, buffer);

    return 0;
}

输出:

$ ./notbug 
Write number: 
4
Write phrase: 
phrase :D


You wrote:4 and "phrase :D
"

基本问题是scanf模式%[^\\n]与不是换行符的一个或多个字符匹配。 因此,如果下一个字符换行符,则模式将失败并且scanf将立即返回而不会读取任何内容。 添加*不会更改该基本事实。 因此,事实证明您不能仅凭一个电话就可以做到这一点,您需要两个:

scanf("%*[^\n]"); scanf("%*c");

请注意,将空白的换行符放在扫描模式中几乎总是无用的,因为它会使scanf读取并丢弃所有空白,直到看到一个非空白字符(它将留在输入缓冲区中)。 特别是如果您尝试在交互式程序中使用它,它将显示为挂起状态,直到您输入非空白行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM