我昨天参加了 Google Code Jam 2019 Round 1C。以下是代码的一部分。
char str[5]={r1,r2,r3,r4,r5};
printf("%s\n", str);
Run Code Online (Sandbox Code Playgroud)
法官给出了错误的答案。但是如果我在打印语句之前添加这一行str[5]='\0';,它就可以工作。
实际上我检查了运行程序,它似乎打印正常。那么,我可以知道为什么法官给出了错误的答案以及哪里出了问题吗?谁能帮忙告诉我打印带有空字符和不带有空字符的字符串的区别?有人可以确认它是否总是给出正确的结果吗?
按照约定,C 字符串以 null 结尾。这意味着printf或任何其他接收 C 字符串的函数将读取指向的内存,直到遇到空字符。
在您的情况下, 中没有空终止符str,因此printf将继续从接下来的内存中读取。这是未定义的行为。当你自己尝试时,你很幸运在之后没有跟随str,所以printf就停在前面了。如果你不太幸运,你可能会遇到垃圾或段错误。这可能就是法官执行代码时发生的情况。
请注意,这str[5] = '\0'也是未定义的行为,因为str[5]超出了数组的大小。
有效的替代解决方案:
包括空终止符:
char str[6]={r1,r2,r3,r4,r5,0};
Run Code Online (Sandbox Code Playgroud)
或者将缓冲区的大小传递给printf:
printf("%.5s\n", str);
Run Code Online (Sandbox Code Playgroud)
或者:
printf("%.*s\n", (int)sizeof(str), str);
Run Code Online (Sandbox Code Playgroud)
或者使用fwrite:
fwrite(str, 1, sizeof(str), stdout);
fputc('\n', stdout);
Run Code Online (Sandbox Code Playgroud)