我在C中初始化一个字符串(字符数组),我注意到即使我在字符串中输入第二个空字符(\ 0),它也会被忽略,并且不会返回任何错误。请参阅下文我的意思:
#include <stdio.h>
int main()
{
char word[]= {'H','e','l','l','o','\0','\0'};
char word2[]= "Hello\0\0";
printf("Word is : %s\n",word); // Prints "Hello"
printf("Word 2 is : %s\n",word2); // Prints "Hello" as well
return 0;
}
你能解释一下原因吗?
答案 0 :(得分:4)
在C中,“字符串”定义为由nul终止的非空字符序列。所以第二个nul不是字符串的一部分。第一个nul标志着结束 - 这就是printf
在使用%s
格式说明符时知道要打印多少个字符的方式。
答案 1 :(得分:3)
不确定您的期望。
任何以'\0'
结尾的字符数组都是字符串。字符串结束后的内容无关紧要,因为字符串已经结束。
这也很好:
const char *two = "hello\0there";
printf("%s\n", two);
打印
hello
嵌入式'\0'
之后的字符无关紧要,它们不是以two
开头的字符串的一部分,因此printf()
无关紧要。
当然,您也可以将剩余的字符视为字符串:
printf("%s\n", two + 6);
这会打印
there
由于后半部分也是一个有效的字符串(像这样的双引文字添加终止符)。所以在某种程度上two
包含两个字符串,这是我的观点。
答案 2 :(得分:2)
NUL字符(如果您正在读取C标准,则为空字符)终止C字符串。它是一个指示器,因此您不需要拉动弦的大小。并且没有什么可以阻止其他值放在缓冲区之后,包括其他NUL字符。事实上,C标准库甚至具有破坏性strtok
函数,该函数将此字符作为“标记化”的一部分放在字符串中。
答案 3 :(得分:1)
C中的大多数字符串操作(例如printf
)知道何时在找到NULL终止符时停止读取字符串。它停止搜索那一点。
实际上,printf
不是为了打印NULL终止符而设计的。 C中的所有字符串都以一个字符串结尾,因此如果它们被打印出来,每个字符串都会有一个&#39; \ 0&#39;在输出中也是如此。那将是毫无意义的。
答案 4 :(得分:1)
在字符串
中忽略第二个空字符
不,它不被忽视。如果你运行这个演示程序
#include <stdio.h>
int main(void)
{
char word[]= {'H','e','l','l','o','\0','\0'};
char word2[]= "Hello\0\0";
printf( "sizeof( word ) = %zu\n", sizeof( word ) );
printf( "sizeof( word2 ) = %zu\n", sizeof( word2 ) );
}
您将获得以下结果
sizeof( word ) = 7
sizeof( word2 ) = 8
这就是所有零字符都包含在字符数组中。
考虑到字符串文字也包含不可见的空终止字符。也就是说,这个字符串文字"Hello\0\0"
(类型为char[8]
)存储在内存中,如{ 'H', 'e', 'l', 'l', 'o', '\0', '\0', '\0' }
。
当使用格式说明符strlen
时,某些函数(例如函数printf
或函数%s
)会忽略冗余零字符,因为这些函数将字符数组视为包含字符串是由零字符分隔的字符序列。
此外,您可以使用零初始化字符数组的所有元素。例如
char s[5] = { '\0' };
此声明相当于
char s[5] = { '\0', '\0', '\0', '\0', '\0' };
或者你甚至可以写
char s[] = "\0\0\0\0";
实际上,此声明等同于数组s
的先前声明,即数组将包含5
个零字符。
如果执行此声明
printf( "%zu\n", sizeof( s ) );
您将按预期获得5
。但是,如果您执行此声明
printf( "%zu\n", strlen( s ) );
或本声明
printf( "%s\n", s );
你会得到0或(在第二种情况下)除了光标将在下一行移动外什么也不会显示..
答案 5 :(得分:0)
你的第二个数组实际上有3 '\0'
个。但请注意,'\0'
或ascii nul 被认为是c中字符串的分隔符,事实上正如其他人在c中所说的那样,字符串只不过是一个字节序列,后跟一个{ {1}}字节。
因此,您应该使用&#34; extra &#34; '\0'
是错误的。事实上,我说&#34; 额外的&#34;因为即使它们是数组的一部分,它们也不是字符串的一部分,并且确保你可以尝试
'\0'
你会看到整个&#34; 示例&#34;如果您使用char string[] = "Example\0Example";
,则'\0'
将不会被打印,printf()
或任何strlen()
*功能也不会将其考虑在内。此外,它原则上有2个str
,显式插入了一个'\0'
,另一个在第二个&#34; 示例&#34;之后隐式添加。