我想读取一个二进制文件,并使用类似于std::string
的东西,它可以自动调整缓冲区大小等。
我正在使用Visual C++。我的选择是什么?
我想读取一个二进制文件,并使用类似于std::string
的东西,它可以自动调整缓冲区大小等。
我正在使用Visual C++。我的选择是什么?
std::string
类已经可以处理带有嵌入NUL字符的数据。你遇到了什么问题?
请注意,在使用.c_str()
方法时,任何嵌入的NUL字符都将终止返回的C-style字符串。
+=
运算符将char*
附加到字符串中。最好使用.assign()
和.append()
方法。 - knownstd::string
实现在.c_str()
上实际上都不会复制任何东西(谁会释放它呢?)。问题不在于.c_str()
本身,而是你将其传递给下一个函数的方式;例如,strlen()
当然会在第一个NUL处停止。 - Greg Hewgillstr.append(buf, 0, sizeof buf);
似乎只会将 buf
中第一个空字符之前的内容追加到字符串中。在这里使用 .append()
后,我从文档中(错误地)得出了 str.size()
将比 .append()
前返回 sizeof buf
更多的结论。 - nosstd::string
应该是安全的,只要你小心使用 .c_str()
方法。请使用 .data()
。
您始终可以使用std :: vector<unsigned char> v
(或您期望的任何类型的输入),然后要访问缓冲区,您只需使用& v [0]
和v.size()
获取大小。
v.data()
代替&v[0]
。 - Charles L Wilcox是的,你可以在std::string
中嵌入空值。
例如:
std::string s;
s.push_back('\0');
s.push_back('a');
assert(s.length() == 2);
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::string
的data()
和c_str()
成员返回const指针,因此内存不可修改,所以使用&buf.front(),您可以直接修改缓冲区的内容。
std::string允许NUL字符,因此您可以直接使用它。
使用c_str()或data()没有问题。是的,嵌入的NUL将在您的数据中,但如果您不使用它们来终止字符串(您需要调用length()来找出字符串中有多少字节),那么一切都会很好。