请参阅以下代码:
int main()
{
char test[3];
scanf("%s", test);
__fpurge(stdin);
printf("%s", test);
}
程序应该只记录3个字符,但是当我键入时,例如8个字符,程序记录所有8个字符!这不应该发生。正确的会记录3个字符,因为scanf
会这样做吗?
答案 0 :(得分:3)
当您将test
传递给scanf()
时,除了指向缓冲区第一个字符的指针外,您只传递任何内容,因此scanf()
不知道您的缓冲区有多大。它会很乐意接受您输入的字符数量,并将它们全部存储在那里。因此,当您键入超过2个字符时,您将导致scanf()
在缓冲区末尾写入字符(加上零asciiz终止符)。通常,在这种情况下预期的是程序崩溃。
您没有遇到崩溃的事实在很大程度上是巧合,可能发生的事情是编译器由于对齐考虑而在堆栈中为超过3个字符分配了空间,可能只有8个字符或更多字符。如果你键入足够的字符,你的程序肯定会崩溃。
出于这个原因,scanf()
的这种用法被认为是完全不安全的。在进行任何严肃的编码时,不应该像scanf()
那样使用"%2s"
。相反,您应该指定字符串的宽度,如下所示:scanf()
。 (请注意,您必须指定一个小于缓冲区大小的数字,以便考虑将由document.add( Chunk.NEWLINE );
自动附加的零asciiz终结符字符。)
答案 1 :(得分:2)
scanf
接受的数据超出test
所能容纳的数据,因为您可以通过%s
无限制地使用%s
。这很危险,必须在生产代码中避免使用。
将%3s
替换为test
以解决此问题。如果要读取三个字符,char test[4];
scanf("%3s", test);
必须为四个字符宽才能容纳空终止符:
//Listing of a program to manage random access files.