字符串的空终止符

36

gcc 4.4.4 c89

如何标准地使字符串以空字符结尾?当我使用NULL时,会收到警告信息。

*dest++ = 0; 
*dest++ = '\0'; 
*dest++ = NULL; /* Warning: Assignment takes integer from pointer without a cast */

源代码:

size_t s_strscpy(char *dest, const char *src, const size_t len)
{
    /* Copy the contents from src to dest */
    size_t i = 0;
    for(i = 0; i < len; i++)
    *dest++ = *src++;

    /* Null terminate dest */
     *dest++ = 0; 

    return i;
}

另一个问题:我故意注释掉了在结尾处加上空字符的那一行。然而,它仍然正确地打印出了 dest 的内容。该函数的调用者将通过包含空字符或不包含空字符来发送字符串的长度,即 strlen(src) + 1 或 strlen(src)。
size_t s_strscpy(char *dest, const char *src, const size_t len)
{
    /* Copy the contents from src to dest */
    size_t i = 0;
    /* Don't copy the null terminator */
    for(i = 0; i < len - 1; i++)
    *dest++ = *src++;

    /* Don't add the Null terminator */
    /* *dest++ = 0; */

    return i;
}

13
在这种情况下,我更喜欢使用 *dest++ = '\0';,因为在这个上下文中,'\0' 的类型是正确的。 - Paul R
5
@Paul R: 为什么不把这个作为答案? - Lucas
为什么在将解引用的值赋值为0之后要对指针进行后置递增操作? - Larry
1
在C语言中,字符数组可能会有一个空字符,从而使该数组成为一个“字符串”。一个“字符串”总是有一个空字符,否则它就不是一个字符串。因此,一个严谨的重写应该是:“如何使用标准方法将字符数组以空字符结尾,从而使其成为一个字符串?” - chux - Reinstate Monica
4个回答

42

关于第一个问题: 我会选择Paul R的评论并以'\0'结束字符串。但是值为0也可以正常工作,这只是个人品味问题。但不要使用指针所用的宏NULL

关于第二个问题: 如果你的字符串没有以\0结尾,可能仍然可以打印出预期的输出,因为在你的内存中,跟随在字符串后面的是一个不可打印字符。虽然可能在你不希望的时候出现错误,但这是一个非常讨厌的bug。一定要以 '\0' 结束一个字符串。


21

13
+1;每次看到“NULL-terminated strings”都让我很烦恼:实际上,字符串终止符不是NULL,而是NUL! - Matteo Italia

18

非常小心: NULL是一个主要用于指针的宏。终止字符串的标准方式是:

char *buffer;
...
buffer[end_position] = '\0';

下面这个代码段同样可行,但是在将整数值分配给int/short/long数组和将字符值分配给它们之间没有太大的区别。这就是为什么首选第一种方式,我个人更喜欢它。

buffer[end_position] = 0; 

'\0' 是 C 语言中的 int 类型常量。 - Antti Haapala -- Слава Україні

7

'\0'是正确的方式。它是一个字符,在字符串中所需,并具有空值。

当我们在C/C++中说null终止字符串时,实际上意味着“零终止字符串”。NULL宏不适用于终止字符串。


'\0',如果它是一个字符,那么它是一个相当大的字符!我相信在今天大多数带有 C 编译器的计算机上,sizeof('\0') == 4。(也许 8031 微控制器是个例外?) - Joseph Quinsey
@Joseph。我不太确定你的意思。在我的编译器上,sizeof('\0') 的结果是1个字节。对于双字节字符,sizeof(L'\0') 是2。 - Scott Langham
6
我已经核实过了:在 .c 文件中是 4,而在 .cpp 文件或使用 g++ 时是 1。这个问题被标记为 C,而不是 C++。 - Joseph Quinsey
2
@Scott 在 C 语言中,\0 是一个 int 类型。尝试在 C 编译器上运行以下代码:printf("%zu\n", sizeof ('\0')); 你的结果肯定会大于 1。 - chux - Reinstate Monica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接