使用不带空字符的printf打印字符串

时间:2019-05-05 03:42:43

标签: c

我昨天参加了Google Code Jam 2019 Round 1C。下面是代码的一部分。

char str[5]={r1,r2,r3,r4,r5};
printf("%s\n", str);

法官给出了错误的答案。但是,如果我在print语句之前添加行str[5]='\0';,它会起作用。

实际上,我检查了运行该程序,看来打印正常。然后,我是否可以知道法官为什么给出错误答案,以及哪里可能出错?谁能告诉我打印带有空字符和不带空字符的字符串的区别吗?有人可以确认是否会始终给出正确的结果吗?

1 个答案:

答案 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);