在 C 中对字符串使用 scanf

Usage of scanf for strings in C

大家好,我对这段代码有疑问:

#define MAX_LIMIT 5
#include <stdio.h>
#include <stdlib.h>
int main()
{
    char S[MAX_LIMIT];
    scanf("%s", S);
    printf("%s\n", S);
}

如您所见,“MAX_LIMIT”的值为 5,所以我不希望字符串“S”的字符数超过 5 个... 当我输入超过这个限制的单词时出现问题。

例如,如果我写“1234567890”,我希望 printf 打印“1234”,但它打印“1234567890”,我不知道为什么... 我也尝试在输入后添加 fflush(stdin);getchar(); 但它不起作用

我试过 fgets(S, MAX_LIMIT, stdin); 并且它有效,但我仍然不明白为什么如果我使用 scanf 它不...

尝试使用 fgets 函数而不是 scanf https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm

第一个问题是scanf 不受限制 - 它无法知道输入缓冲区的实际大小(怎么可能呢?变量S不带来它的大小)。您可以强制 scanf 使用适当的格式读取不超过给定数量的字符,但是格式必须是硬编码的(您 可以 在 运行时间,但代码变得更笨拙了)。

然后,char S[MAX_LIMIT] 将分配 至少 MAX_LIMIT 个字符,但是这个数字可能会被编译器为了优化目的向上舍入(给你一个不可信的、依赖于平台的“缓冲区”),并分配在一个可写区域,这样你就可以用额外的输入覆盖信息。在需要或重新初始化额外信息之前,您可能不会注意到任何问题。

为了避免这些问题,您可以使用 fgets,然后在生成的缓冲区上使用 运行 sscanf

您需要在 scanf 格式字符串中加入限制:

scanf("%4s", S);

注意,限制比数组的大小小一(因为终止 NUL 不计入输入字符之一需要 space),并且需要直接在字符串作为整数(使得难以使用符号或可变长度)。此外,如果输入超过 4 个(非白色space)字符,则只读取前 4 个,其余的将留在输入缓冲区中以供稍后读取。