我有一个缓冲区,我不希望用户输入的字符多于缓冲区可容纳的字符数(以避免缓冲区溢出)。
我正在使用scanf
,并且这样做了:
char buffer[30] = {'\0'};
scanf("%30s", buffer);
但是,如果用户输入的数量超过30,我知道我受到了保护。但是,如果用户输入的数量超过30,那么缓冲区是否会被终止?
答案 0 :(得分:2)
来自scanf
手册:
s 匹配一系列 非空白字符;下一个 指针 必须是指向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);
您还应该检查用户是否输入了返回/换行符,如果他有以下内容则终止scanf
:
scanf("%" xstr(BUFSIZE) "[^\n]s%[^\n]*", buf);
最好检查返回值,所以:
int rc = scanf("%" xstr(BUFSIZE) "[^\n]s%[^\n]*", buf);
最后,检查是否剩下任何内容(例如换行符,然后使用它):
if (!feof(stdin))
getchar();
答案 1 :(得分:2)
scanf()
会在缓冲区中添加一个终止空字符。
但是,你要30个字符,这实际上意味着31个字符,只有30个字符。你应该使用最大字段宽度为29。
char buffer[30] = {'\0'};
scanf("%29s", buffer);
另请注意,转换说明符"%c"
与"%s"
非常相似,但不会添加终止空字符,也不会丢弃输入中的空格。根据您的期望,它可能比使用“%s”更好。
char buffer[30] = {'\0'};
scanf("%29c", buffer);
buffer[29] = '\0';
答案 2 :(得分:1)
您将有一个缓冲区溢出,因为您没有允许终止NUL字符。像这样声明你的缓冲区:
char buffer[31];
你会没事的。