2

我有一个缓冲区,我不希望用户输入的字符多于缓冲区可以容纳的字符(以避免缓冲区溢出)。

我正在使用scanf并且已经这样做了:

char buffer[30] = {'\0'};
scanf("%30s", buffer);

但是,我知道如果用户输入超过 30 个,我会受到保护。但是,如果用户输入超过 30 个,缓冲区是否会以空值终止?

4

3 回答 3

2

scanf()使用“%s”转换说明符将终止空字符添加到缓冲区。

但是,您要求 30 个字符,这实际上意味着 31,并且只有 30 个空间。您应该使用 29 的最大字段宽度。

char buffer[30] = {'\0'};
scanf("%29s", buffer);

另请注意,转换说明符的"%c"工作方式与 非常相似"%s",但不添加终止空字符,也不丢弃输入中的空格。根据您的期望,它可能比使用“%s”更好。

char buffer[30] = {'\0'};
scanf("%29c", buffer);
buffer[29] = '\0';
于 2009-11-12T09:59:53.503 回答
2

scanf手册:

s 匹配一系列非空白字符;next 指针必须是指向 char 的指针,并且数组必须足够大以接受所有序列和终止 NUL 字符。输入字符串在空白处或最大字段宽度处停止,以先发生者为准。

您正在调用 UB。尝试:

#define str(x) #x
#define xstr(s) str(x)
#define BUFSIZE 30

char buffer[ BUFSIZE + 1 ];
scanf("%" xstr(BUFSIZE) "s", buf);

要忽略BUFSIZE字符以外的任何内容,请抑制赋值:

scanf("%" xstr(BUFSIZE) "s%*", buf);

您还应该检查用户是否输入了 return/newline 并scanf在他有以下情况时终止:

scanf("%" xstr(BUFSIZE) "[^\n]s%[^\n]*", buf);

检查返回值是一个好习惯,所以:

int rc = scanf("%" xstr(BUFSIZE) "[^\n]s%[^\n]*", buf);

最后,检查是否还有任何东西(例如换行符,并使用它):

if (!feof(stdin))
    getchar();
于 2009-11-12T09:48:28.843 回答
1

您将遇到缓冲区溢出,因为您不允许使用终止 NUL 字符。像这样声明你的缓冲区:

char buffer[31];

你会没事的。

于 2009-11-12T09:47:24.193 回答