我有一个缓冲区,我不希望用户输入的字符多于缓冲区可以容纳的字符(以避免缓冲区溢出)。
我正在使用scanf
并且已经这样做了:
char buffer[30] = {'\0'};
scanf("%30s", buffer);
但是,我知道如果用户输入超过 30 个,我会受到保护。但是,如果用户输入超过 30 个,缓冲区是否会以空值终止?
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';
从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();
您将遇到缓冲区溢出,因为您不允许使用终止 NUL 字符。像这样声明你的缓冲区:
char buffer[31];
你会没事的。