我正在尝试打印给定程序中的所有 4 个字符串。但我无法打印字符串。使用下面的代码,我得到了一些奇怪的输出。
int main()
{
char szStr[] = "India\0Japan\0America\0Australia";
char *p = szStr;
while(p)
{
printf("%c", p);
p++;
}
return 0;
}
while(p)
是相同的
while(p != NULL)
这当然总是正确的——字符串文字指向一个有效的内存位置。我觉得你把这与
while(*p)
或等效的
while(*p != 0)
因为这会一直运行,直到它在字符串中找到 0 终止符。不过,这也不够好。你不知道你刚刚打印了哪个字符串。您必须手动跟踪字符串的数量。另外,为什么要逐个字符地打印它,printf()
为显示的每个字节调用相当昂贵的函数?这只是浪费。像这样的东西怎么样
char szStr[] = "India\0Japan\0America\0Australia";
char *p = szStr;
for (int i = 0; i < 4; i++) {
puts(p);
p += strlen(p) + 1;
}
不过,我不明白为什么这比简单地存储字符串数组更简单或更好。像这样:
const char *strings[] = {
"India",
"Japan",
"America",
"Australia"
};
for (int i = 0; i < sizeof(strings) / sizeof(strings[0]); i++)
puts(strings[i]);
这是经过测试和工作的:
#include <stdio.h>
int main()
{
char szStr[] = "India\0Japan\0America\0Australia\0";
char *p = szStr;
while(*p)
{
p += printf("%s", p);
p++;
fputc('\n', stdout);
}
return 0;
}
请注意字符串上的额外空终止符。这实际上很重要,尽管字符串文字有它自己的空项。双空项是正确终止 while 循环所必需的。
printf
返回写入的字符数,即每个字符串的长度,不包括空终止符。因此,当您将其添加到 时p
,您只需要p
指向空终止符。再次递增p
,您将处于下一个字符串的开头。如果该字符串的长度为 0,则p
再次指向空终止符,因此 while 循环将退出。这就是为什么您需要在字符串末尾添加额外的空终止符。
请记住,这*p
会让您获得p
.
这将起作用:
int main()
{
char szStr[] = "India\0Japan\0America\0Australia\0";
char *p = szStr;
int numOfStrings = 4;
for(int i = 0; i < numOfStrings; i++)
{
while(*p)
{
printf("%c", *p);
p++;
}
printf(" "); //print a space character to separate your strings
p++; //advance pointer to skip '\0' between strings
}
return 0;
}
%c
是用于打印单个字符的格式说明符。改为使用%s
。仍然 printf 只会打印字符串到第一个\0
字符。如果要输出四个字符串,则必须在打印前执行某种拆分。也许sscanf
与"%s%s%s%s"
.
将行更改while(p)
为while(*p)
。
在c
中,除 0 以外的任何值都将被视为真,而 0 将被视为假。
所以,p
不是 0,它使while
循环一次又一次地重复。
但是*p
会在字符串的末尾变为 0。