开始C:行为打印字符串

开始C:行为打印字符串,c,C,我正在学习C语言,目前正在尝试将字符串存储在变量中。我把下面的内容放在一起尝试不同的东西 #include <stdio.h> int main() { char *name = "Tristan"; char today[] = "January 1st, 2016"; char newyear[] = {'H','a','p','p','y',' ','N','e','w',' ','Y','e','a','r','!','\n'}; printf

我正在学习C语言,目前正在尝试将字符串存储在变量中。我把下面的内容放在一起尝试不同的东西

#include <stdio.h>
int main() {
    char *name = "Tristan";
    char today[] = "January 1st, 2016";
    char newyear[] = {'H','a','p','p','y',' ','N','e','w',' ','Y','e','a','r','!','\n'};
    printf("Hello world!\n");
    printf("My name is %s.\n", name);
    printf("Today is: %s.\n", today);
    printf(newyear);
    return 0;
}
这正是我所期望的,为什么“2016年1月1日”会在节目结束时再次打印出来

如果我从“newyear”数组中取出“\n”,它将不会执行此操作


有人能解释一下原因吗?

newyear
遗漏了一个尾随的空字节,因此
printf
认为这是未定义的行为。
只有字符串文本隐式附加空字节。您显式初始化每个字符,因此不会追加空字节

未定义的行为意味着标准在这种情况下没有定义的事情将会发生。这包括什么都没有发生,你哭了,或者,是的,把一些字符串打印了两次

只需在数组中添加一个附加字符,即空字节,即可解决此问题:

char newyear[] = {'H','a','p','p','y',' ','N','e','w',' ','Y','e','a','r','!','\n', '\0'};


注意没有一个理智的人会用这样的字符串初始化自动
char
数组。只需坚持字符串文字!(我认为您这样做只是为了学习。)

记住,C中的字符串以特殊的
'\0'
字符结尾


在被视为字符串的数据末尾没有此终止符将导致未定义的行为,因为字符串函数通过搜索终止符的数据结尾。

这是因为您直接将
新年定义为
字符
数组,而不是通过字符串文本
语法。这将防止编译器添加标记字符串结尾所需的尾随
\0
字符


由于
newyear
today
都位于堆栈上,在这种情况下,它们在那里有连续的存储,因此
printf
newyear
\n
之后保存,并打印内存内容,直到找到
\0

newyear
应该以
'\0'
结束,而不是
换行
,作为C字符串。然后,您可以将
换行符
放入
printf
语句中,就像其他语句一样:

char newyear[] = {'H','a','p','p','y',' ','N','e','w',' ','Y','e','a','r','!','\0'};
//...
printf("%s.\n", newyear);
或者,您可以将字符串终止符添加到数组中,并使用
printf

char newyear[] = {'H','a','p','p','y',' ','N','e','w',' ','Y','e','a','r','!','\n','\0'};
//...
printf(newyear);

在前两个示例中,定义为
“我的字符串”
的字符串由编译器自动附加
'\0'

newyear
应以
'\0'
结束,而不是
换行
,作为C字符串。将
换行符
放在
printf
语句中,就像其他语句一样,或者按照您的方式,在
'\n'
之后添加
'\0'
。这一行:
printf(新年)在启用所有警告的情况下编译时,将导致编译器输出警告:
:9:5:警告:格式不是字符串文字且没有格式参数[-Wformat security]
请记住
printf()
的第一个参数是字符串文字。即以NUL字节结束。所以语句应该是:
printf(“%16c”,新年)尽管更好的是:
printf(“%15c\n”,新年)因为在DOS和Windows上换行序列不止一个的情况下,这将正常工作character@Barmar完成。对不起,忘了。谢谢你的解释。
char newyear[] = {'H','a','p','p','y',' ','N','e','w',' ','Y','e','a','r','!','\n','\0'};
//...
printf(newyear);