scanf不要超过缓冲区溢出

时间:2009-11-12 09:42:42

标签: c gcc c99

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

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

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

但是,如果用户输入的数量超过30,我知道我受到了保护。但是,如果用户输入的数量超过30,那么缓冲区是否会被终止?

3 个答案:

答案 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)

带有“%s”转换说明符的

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];

你会没事的。