如何将二进制数据推入std :: string?

3
我将尝试以下方式创建二进制文件:
```python ```
string buf;
...
buf += filename.length();
buf += filename;

等等。首先我会用二进制格式给出长度,但是如何将其转换成4字节字符数组或2字节字符数组等呢?基本上,我想实现与以下相同的功能:

int len = filename.length();
fwrite(&len, sizeof(len), 1, fp);

这个方法可以正常工作,但将它放在一个字符串中可能更容易处理。

编辑:我不想使用流或向量,我正在尝试弄清楚是否可以使用字符串实现。

4个回答

4

使用流是更好的选择。不要使用字符串


1
stringstream怎么样? :-) - Kerrek SB
@daniel,使用字符串无法实现这个吗? - Rookie
你正在处理二进制数据,而不是人类可读的字符串。 - Daniel A. White
这是因地制宜的。你不会用一匹Shirehorse参加大国家比赛,也不会用一匹Thoroughbred来耕田。 - graham.reeds
3
@graham.reeds,我的观点是,如果我因为别人认为学习某些东西不是最好的选择而被禁止学习,那么我将成为一个盲从他人意见的绵羊...我想学习这个东西只是因为我想学。我不在乎它是否有用,但它肯定会教我一些我以前不知道的关于C ++的新东西。 - Rookie
显示剩余5条评论

2

只需使用std:vector<unsigned char>,并使用istream或ostream迭代器将数据读取/写入向量中。例如,要从文件中读取,可以执行以下操作:

vector<unsigned char> binary_buffer;

ifstream in_file("my_binary_file.bin", ios_base::binary | ios_base::in);
istream_iterator<unsigned char> end_of_file;
istream_iterator<unsigned char> in_file_iter(in_file);

while (in_file_iter != end_of_file)
{
    binary_buffer.push_back(*in_file_iter++);
}

输出将更加简单:
ofstream out_file("another_binary_file.bin", ios_base::binary | ios_base::out);
ostream_iterator<unsigned char> binary_output(out_file);
copy(binary_buffer.begin(), binary_buffer.end(), binary_output);

1
std::string是二进制保存的,可以用作字节数组。 - Ludger Sprenker
2
@Ludger:使用std::string至少在第一眼看上去意味着您想将此类数据视为文本字符串,而使用std::vector<unsigned char>则清楚地表明它只是一个二进制块。 - Matteo Italia
@matteo,我只是在想,为什么字符串允许二进制数据存在,如果它永远不应该那样使用呢? - Rookie
“允许二进制数据”只是文本字符串仅仅是一种特殊类型的二进制数据的结果。std::stringstd::vector<unsigned char>之间的区别并不在于数据的存储方式(两者都可以将任何字符存储在连续的数组中),而在于它将如何使用,因此在它们提供的方法上也有所不同(std::string具有通常用于字符串的方法,转换为/从C字符串等)。 - Matteo Italia

2
是的,这是可以做到的,因为这是C++,在C++中一切皆有可能。
首先,以下是如何实现它,然后我将回答为什么你可能需要这样做的问题:
“最初的回答”
std::ifstream input( "my.png", std::ios::binary );
std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
int buffSize = buffer.size();
std::string myString(buffer.begin(), buffer.end());

在我的情况下,我使用的框架中,HTTP客户端仅支持将字符串作为post消息体,但我需要将文件的原始二进制数据发布到我正在使用的服务。我可以在库的内部进行修改(不好),也可以为简单的文件发布引入另一个不必要的依赖项(也不太好)。但是由于字符串能够保存这些数据,因此我能够读取文件,将其复制到字符串中,然后上传。
这是一个不幸的处境,但在某些情况下还是有用的。通常,您可能希望做一些不同的事情。这并不是很清晰易懂,而且您会从复制中获得一些性能损失,但它可行,并有助于了解其工作原理。std :: string 以二进制格式在内部保存数据连续,就像vector一样,并且可以从向量中的迭代器初始化。 unsigned char长度为1字节,因此它类似于byte值。字符串将字节复制到自身,因此您最终得到精确的数据。

2

使用向量来存储数据,或者通过流直接将其写入文件。


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