具有空字符数据的 std::string 等效形式是什么?

4

我想读取一个二进制文件,并使用类似于std::string的东西,它可以自动调整缓冲区大小等。

我正在使用Visual C++。我的选择是什么?


你想将整个文件读入到std :: string中吗? - Jacob
他基本上是在询问二进制安全字符串。std::string是否是二进制安全的? - Cem Kalyoncu
2
为什么在二进制文件中使用std::string? - Idan K
1
请尝试使用std::vector<char>。 - orip
5个回答

11

std::string类已经可以处理带有嵌入NUL字符的数据。你遇到了什么问题?

请注意,在使用.c_str()方法时,任何嵌入的NUL字符都将终止返回的C-style字符串。


我遇到的问题是使用+=运算符将char*附加到字符串中。最好使用.assign().append()方法。 - known
你说的“任何嵌入的NUL字符都将终止返回的C风格字符串”是什么意思?.c_str()将返回std::string的所有字符,然后是额外的\0。这不像.c_str()在第一个\0之后停止复制字符。当然,如果你只有那个const char*,你就不知道哪个\0是最后一个。 - MSalters
1
@MSalters:我熟悉的所有std::string实现在.c_str()上实际上都不会复制任何东西(谁会释放它呢?)。问题不在于.c_str()本身,而是你将其传递给下一个函数的方式;例如,strlen()当然会在第一个NUL处停止。 - Greg Hewgill
还有其他需要考虑的问题。例如,str.append(buf, 0, sizeof buf); 似乎只会将 buf 中第一个空字符之前的内容追加到字符串中。在这里使用 .append() 后,我从文档中(错误地)得出了 str.size() 将比 .append() 前返回 sizeof buf 更多的结论。 - nos

8

std::string 应该是安全的,只要你小心使用 .c_str() 方法。请使用 .data()


-1,你甚至不知道内部表示是否在连续的内存中(这取决于实现),因此data()非常危险。 - orip
9
可以的(只要库符合标准)。根据C++标准,第21.3.6.3点:“如果size()不为零,则成员[data() const]返回一个指向数组初始元素的指针,该数组的前size()个元素等于由*this控制的字符串的相应元素。” - liori

6

您始终可以使用std :: vector<unsigned char> v(或您期望的任何类型的输入),然后要访问缓冲区,您只需使用& v [0]v.size()获取大小。


1
在使用C++11时,我建议使用v.data()代替&v[0] - Charles L Wilcox

3

是的,你可以在std::string中嵌入空值。

例如:

std::string s;
s.push_back('\0');
s.push_back('a');
assert(s.length() == 2);

注意:std::string的c_str()成员函数总是会在返回的char缓冲区中添加一个空字符;然而,std::string的data()成员函数可能会在返回的char缓冲区中添加一个空字符,也可能不添加。
要小心operator+=
需要注意的一件事是不要在右侧使用带有char*参数的operator+=。它只会添加到空字符为止。
例如:
std::string s = "hello";
s += "\0world";
assert(s.length() == 5);

正确的方式:

std::string s = "hello";
s += std::string("\0world", 6);
assert(s.length() == 11);

存储二进制数据更常使用std::vector

通常情况下,使用std::vector来存储任意二进制数据更为普遍。

std::vector<char> buf;
buf.resize(1024);
char *p = &buf.front();

由于std::stringdata()c_str()成员返回const指针,因此内存不可修改,所以使用&buf.front(),您可以直接修改缓冲区的内容。


0

std::string允许NUL字符,因此您可以直接使用它。

使用c_str()或data()没有问题。是的,嵌入的NUL将在您的数据中,但如果您不使用它们来终止字符串(您需要调用length()来找出字符串中有多少字节),那么一切都会很好。


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