C语言 scanf() 留下换行符在缓冲区问题

C语言中,scanf() 函数读取输入时,通常会留下换行符(\n)在输入缓冲区中,这会导致一些问题,尤其是在使用后续的输入函数(如 gets() 或 fgets())时。scanf() 并不会从缓冲区中移除多余的换行符,这就导致后续输入函数会读取到这个换行符而不是用户的实际输入。本文主要介绍scanf() 留下换行符在缓冲区问题的解决方法。

scanf() 留下换行符在缓冲区问题

当使用 scanf() 读取输入时,像 %d%f 这样的格式说明符会跳过空白字符(包括空格、制表符和换行符)来读取数据。然而,scanf() 并不会从缓冲区中移除多余的换行符,这就导致后续输入函数会读取到这个换行符,而不是用户的实际输入。

#include <stdio.h>

int main() {
    int number;
    char str[20];

    printf("Enter a number: ");
    scanf("%d", &number);

    // 读取字符数组
    printf("Enter a string: ");
    gets(str);  // 这里将直接读取到换行符

    printf("Number: %d\n", number);
    printf("String: %s\n", str);

    return 0;
}

解决方法

1、使用 getchar() 清除换行符

scanf() 之后调用 getchar() 来手动读取并丢弃缓冲区中的换行符。

#include <stdio.h>

int main() {
    int number;
    char str[20];

    printf("Enter a number: ");
    scanf("%d", &number);

    // 使用 getchar() 清除缓冲区中的换行符
    getchar();

    printf("Enter a string: ");
    gets(str);

    printf("Number: %d\n", number);
    printf("String: %s\n", str);

    return 0;
}

2、使用 fgets() 代替 gets()

fgets() 是一个更安全的读取字符串的方法,它可以防止缓冲区溢出并正确处理换行符。fgets() 不会忽略换行符,但会将它作为输入的一部分存储在字符串中。可以手动移除换行符,如不希望它出现在字符串的末尾。

#include <stdio.h>

int main() {
    int number;
    char str[20];

    printf("Enter a number: ");
    scanf("%d", &number);

    // 使用 getchar() 清除缓冲区中的换行符
    getchar();

    // 使用 fgets() 读取字符串
    printf("Enter a string: ");
    fgets(str, sizeof(str), stdin);
    
    // 移除换行符
    //str[strcspn(str, "\n")] = 0;

    printf("Number: %d\n", number);
    printf("String: %s\n", str);

    return 0;
}

3、使用 scanf(" %c") 格式符

通过在 scanf() 格式符之前添加一个空格,可以强制跳过所有空白字符(包括换行符)。

#include <stdio.h>

int main() {
    int number;
    char str[20];

    printf("Enter a number: ");
    scanf("%d", &number);

    // 使用 " %[^\n]" 读取字符串,跳过换行符
    printf("Enter a string: ");
    scanf(" %[^\n]", str);

    printf("Number: %d\n", number);
    printf("String: %s\n", str);

    return 0;
}

推荐阅读
cjavapy编程之路首页