2009-11-12 116 views
1

C99 gccscanf不超过缓冲区溢出

我有一个缓冲区,我不想让用户输入以避免缓冲区溢出。

我使用scanf函数,并这样做:

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

但是,我知道,如果用户输入30多家。但是,如果用户输入超过30将缓冲是我的保护null终止?

非常感谢您的任何建议,

回答

1

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'; 
1

你将有一个缓冲区溢出,因为你还没有允许终止NULL字符。声明你的缓冲区是这样的:

char buffer[31]; 

你会没事的。

2

scanf手册:

小号匹配的 非空白字符的序列;下一个 指针 必须是一个指向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();