为什么std :: string("\ x00")报告长度为0?

Ada*_*ski 27 c++ stdstring string-length c++11

我有一个需要编码字符串的函数,它需要能够接受0x00作为有效的'字节'.我的程序需要检查字符串的长度,但是如果我传递"\x00"std::stringlength()方法返回0.

即使字符串是单个空字符,如何获得实际长度?

Sil*_*olo 45

std::string完全能够存储空值.但是,你必须保持警惕,你必须非常谨慎const char*地构建一个const char*,你可以从中创建std::string.

std::string a("\x00");
Run Code Online (Sandbox Code Playgroud)

这将创建一个仅包含空字符的常量C字符串,后跟一个空终止符.但C字符串不知道它们有多长; 所以字符串认为它运行直到第一个空终止符,这是第一个字符.因此,创建了一个零长度的字符串.

std::string b("");
b.push_back('\0');
Run Code Online (Sandbox Code Playgroud)

std::string是空的.Characters(\0)也可以自由地为零字节.所以,在这里,没有什么能阻止我们正确阅读数据结构.长度b将是1.

通常,您需要避免构造包含空字符的C字符串.如果您直接从文件中读取输入std::string或确保一次按下一个字符,则可以获得所需的结果.如果你真的需要一个带有空字符的常量字符串,可以考虑使用一些其他的标记字符代替\0然后(如果你真的需要它)'\0'在加载后替换那些字符std::string.

  • _"但C字符串不知道它们有多长"_ - 更确切地说,`std :: string("\ x00")`首先创建一个类型为`const char [2]的*字符串文字*,所以此时尺寸仍然众所周知.虽然这个数组衰变为`const char*`,它被传递给`std :: string`构造函数.此时数组大小"丢失",因为构造函数只能扫描第一个`\ 0`来确定大小.从理论上讲,`std :: string` c'tor可能会有一个数组的重载,这将允许在字符串文字中嵌入`\ 0`. (22认同)
  • @Ruslan所以?这本来是完全可以接受的.当然它也是愚蠢的,因为它破坏了C字符串文字约定,因此在大多数情况下违反了用户的期望(没有人想要在将它初始化为`std :: string(')时在其字符串中找到空字符. HI")`). (4认同)

Sid*_*d S 28

你传入一个空字符串.请std::string(1, '\0')改用.

或者std::string{ '\0' }(谢谢,@ zett42)

  • 更短:`std :: string {'\ 0'}` (8认同)

Erb*_*ica 24

使用C++ 14,您可以使用字符串文字运算符来存储具有空字节的字符串:

using namespace std::string_literals;

std::string a = "\0"s;
std::string aa = "\0\0"s; // two null bytes are supported too
Run Code Online (Sandbox Code Playgroud)

  • 只是`使用命名空间std :: literals;`也可以. (6认同)
  • @ sp2danny ...但也可能引入其他不需要的文字运算符(例如来自`std :: literals :: chrono_literals`). (5认同)