【发布时间】:2017-04-29 04:08:08
【问题描述】:
当字符数组substring[#]设置为[64]时,文件输出一个附加字符。附加字符因每次编译而异。有时es?,有时esx等等。
如果我将 [64] 更改为任何其他数字(至少我尝试过的数字:65、256、1..),它会正确输出为 es。
更奇怪的是,如果我将未使用/未声明的字符数组 char newString[64] 留在此文件中,即使是 64,它也会输出正确的子字符串 es。
- 看似随意的 64 大小如何影响输出?
- 完全不相关的字符数组 (
newString) 如何影响另一个字符数组的输出?
.
int main () {
char string[64];
char newString[64];
char substring[64];
fgets(string,64,stdin);
strncpy(substring, string+1, 1);
printf("%s\n", substring);
return 0;
}
【问题讨论】:
-
注意
strncpy的正确使用;它不附加终止零。看起来好像您认为它会从另一个子字符串中“提取”一个子字符串。 -
您的程序有未定义的行为。因此,您问题的整个前提都是错误的-要求对 UB 的行为进行解释是没有意义的。您的问题应该是 - 我的代码中的错误在哪里。答案可能在这里:
strncpy(substring, string+1, 1)。string+1跳过整个字符串缓冲区并指向它后面的字节。而且您也只复制 1 个字节,然后尝试将其打印为字符串。 -
你的意见是什么?
-
@kaylum: "
string+1跳过整个字符串缓冲区..." - 这不是真的。string+1指向string[1],完全符合 OP 的意图。它不会跳过整个缓冲区。行为确实是未定义的,但出于完全不同的原因(参见 iharob 的回答) -
如果您希望得到明确定义的行为,初始化缓冲区通常是个好主意。因此,我会将您的变量声明更改为如下所示:
char string[64] = {0};