我正尝试通过scanf
读取字符串,如下所示:
char input[8];
scanf("%s",input);
事实证明,该程序可以读取8个以上的字符。假设我输入了123456789012345,strlen(input)返回了15。
但是,当我将输入设置为:
char input[4];
scanf("%s",input);
输入“ 12345”将导致“ 16146分段错误”。 有人知道怎么回事吗?
答案 0 :(得分:8)
从技术上讲,两种情况都调用未定义的行为。第一种情况恰好在您的系统上工作并不意味着您的程序已定义良好。测试只能指示错误的存在,而不能指示错误的存在。
由于您仍在学习CI,因此我们将趁机为您提供有关从stdin
读取输入的建议:始终将要读取的输入长度限制为正在读取的缓冲区的长度,在结尾处保留一个空终止符。
如果您想使用scanf
从stdin
中读取字符串,那么比使用原始的"%s"
更安全的是,在字符串格式说明符前加上字符串的最大长度。 。例如,如果我有一个char buffer[20];
是调用scanf
的目的地,那么我将使用格式字符串"%19s"
。
答案 1 :(得分:1)
这都是所谓的未定义行为,应不惜一切代价避免。找不到像这样引起的漏洞那么棘手的错误。
那为什么行得通呢?好吧,这就是不确定行为的问题。它可能会起作用。您根本无法保证。
在此处了解有关UB的更多信息:Undefined, unspecified and implementation-defined behavior