在字符串中使用空字符(C ++)

时间:2012-07-20 15:27:27

标签: c++ string arrays null-character

我正在刷新我的C ++,偶然发现了一个关于字符串,字符数组和空字符('\0')的奇怪行为。以下代码:

#include <iostream>
using namespace std;

int main() {
    cout << "hello\0there"[6] << endl;

    char word [] = "hello\0there";
    cout << word[6] << endl;

    string word2 = "hello\0there";
    cout << word2[6] << endl;

    return 0;
}

产生输出:

> t
> t
>

幕后发生了什么?为什么字符串文字和声明的char数组在索引6(在内部't'之后)存储'\0',但声明的字符串不存在?

4 个答案:

答案 0 :(得分:10)

根据我的记忆,前两个本质上只是一个数组,打印字符串的方式是继续打印,直到遇到\0。因此,在前两个示例中,您从字符串中第6个字符的点偏移量开始,但在您的情况下,您将打印出第{6个字符t

string类会发生什么,它会将字符串的副本复制到它自己的内部缓冲区中,并通过将字符串从数组的开头复制到第一个\0来实现。认定。因此,t未存储,因为它位于第一个\0之后。

答案 1 :(得分:5)

因为std::string构造函数将const char*视为C样式字符串。它只是从它复制,直到它达到空终止符,然后停止复制。

所以你的最后一个例子实际上是在调用未定义的行为; word2[6]越过字符串的结尾。

答案 2 :(得分:4)

您正在构建一个来自char*的字符串(或者腐烂的东西)。这意味着适用于C字符串的约定。那就是他们被'\0'终止了。这就是word2仅包含"hello"

的原因

答案 3 :(得分:0)

问题在于您根本不打印字符串 - 您正在打印单个字符。

char word [] = "hello\0there";//Array of char...
cout << word[6] << endl;      //So word[6] is the char't' (NOT a string)

string word2 = "hello\0there"; //std::string...
cout << word2[6] << endl;      //so word2[6] is the char 't' (NOT a string as well)

所以,你正在调用“char”重载,而不是“char *”或“string”重载,并且NULL字符完全与它无关:你只是打印第6个字符,和word2的第6个字符。

如果我正确地阅读您的意图,您的测试应该是:

cout << &(word[6]) (char*, should print "there")
cout << &(word2[6]) (char* as well, undefined behaviour pre-C++11)

在C ++ 11及更高版本中,这也将打印“there”And be well defined