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