简体   繁体   English

scanf不超过缓冲区溢出

[英]scanf not to exceed buffer overrun

I have a buffer and I don't want the user to enter more characters than the buffer can hold (to avoid a buffer overrun). 我有一个缓冲区,并且我不希望用户输入的字符超出缓冲区可以容纳的字符数(以避免缓冲区溢出)。

I am using scanf and have done like this: 我正在使用scanf并已完成以下操作:

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

However, I know I am protected if the user enters more than 30. However, if the user enters more than 30, will the buffer be null terminated? 但是,我知道如果用户输入的字符数超过30,我将受到保护。但是,如果用户输入的字符数超过30,缓冲区是否将被终止为null?

From the scanf manual: scanf手册中:

s Matches a sequence of non-white-space characters; s匹配一系列非空格字符; the next pointer must be a pointer to char, and the array must be large enough to accept all the sequence and the terminating NUL character. 下一个指针必须是指向char的指针,并且数组必须足够大以接受所有序列和终止NUL字符。 The input string stops at white space or at the maximum field width, whichever occurs first. 输入字符串停在空白处或最大字段宽度处,以先到者为准。

You are invoking UB. 您正在调用UB。 Try: 尝试:

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

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

To ignore anything beyond BUFSIZE characters suppress assignment: 要忽略BUFSIZE字符以外的任何内容,禁止分配:

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

You should also check if the user has entered return/newline and terminate scanf if he has: 您还应该检查用户是否输入了return /换行符,并在scanf情况时终止了scanf

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

and it is good practice to check for return values, so: 并且最好检查返回值,因此:

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

and finally, check if the there's anything left (such as the newline, and consume it): 最后,检查是否还有剩余的内容(例如换行符并使用它):

if (!feof(stdin))
    getchar();

scanf() with a "%s" conversion specifier adds a terminating null character to the buffer. 具有“%s”转换说明符的scanf()向缓冲区添加一个终止的空字符。

But , you're asking for 30 characters, which really means 31 and only have space for 30. You should use a maximum field width of 29. 但是 ,您要输入30个字符,这实际上意味着31个字符,并且只能有30个空格。您应该使用最大字段宽度为29。

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

Also note that the conversion specifier "%c" works pretty much like "%s" , but does not add the terminating null character and does not discard space from the input. 还要注意,转换说明符"%c"工作方式与"%s"非常相似,但是不会添加终止的空字符,也不会从输入中丢弃空格。 Depending on what you expect, it might be better than using "%s". 根据您的期望,它可能比使用“%s”更好。

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

You will have a buffer overrun because you haven't allowed for the terminating NUL character. 由于不允许使用终止NUL字符,因此会有缓冲区溢出。 Declare your buffer like this: 这样声明缓冲区:

char buffer[31];

and you will be fine. 你会没事的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM