C++ c++;:使用字节

C++ c++;:使用字节,c++,io,numbers,C++,Io,Numbers,我的问题是,我需要加载一个二进制文件并使用文件中的单个位。在那之后,我当然需要将它保存为字节 我的主要问题是-选择什么数据类型在-char或long int中工作?我能用chars吗?你的句子不是真正正确的英语,但就我所能解释的问题而言,你最好使用unsigned char(一个字节)类型来分别修改每个字节 编辑:根据注释进行更改。这实际上只是取决于您想要做什么,但我想说的是,一般来说,最好的速度是保持编译程序所用整数的大小。如果你有一个32位的程序,那么选择32位整数,如果你有64位,那么选择

我的问题是,我需要加载一个二进制文件并使用文件中的单个位。在那之后,我当然需要将它保存为字节


我的主要问题是-选择什么数据类型在-char或long int中工作?我能用chars吗?

你的句子不是真正正确的英语,但就我所能解释的问题而言,你最好使用unsigned char(一个字节)类型来分别修改每个字节


编辑:根据注释进行更改。

这实际上只是取决于您想要做什么,但我想说的是,一般来说,最好的速度是保持编译程序所用整数的大小。如果你有一个32位的程序,那么选择32位整数,如果你有64位,那么选择64位


如果文件中有一些字节,或者有整数,则情况可能不同。在不知道文件的确切结构的情况下,很难确定最佳值是什么。

如果要处理字节,最好的方法是使用特定大小的类型

#include <algorithm>
#include <iterator>
#include <cinttypes>
#include <vector>
#include <fstream>

int main()
{
     std::vector<int8_t> file_data;
     std::ifstream file("file_name", std::ios::binary);

     //read
     std::copy(std::istream_iterator<int8_t>(file),
               std::istream_iterator<int8_t>(),
               std::back_inserter(file_data));

     //write
     std::ofstream out("outfile");           
     std::copy(file_data.begin(), file_data.end(),
               std::ostream_iterator<int8_t>(out));

}
#包括
#包括
#包括
#包括
#包括
int main()
{
std::矢量文件_数据;
std::ifstream文件(“文件名”,std::ios::binary);
//阅读
std::copy(std::istream_迭代器(文件),
std::istream_迭代器(),
std::back_inserter(文件数据));
//写
标准:流出(“流出口”);
std::copy(文件\数据.begin(),文件\数据.end(),
std::ostream_迭代器(out));
}

编辑修复错误

除非性能是关键任务,否则请使用任何使代码易于理解和维护的工具

在开始编写任何东西之前,请确保您理解它们,以及它们可能是怎样的。

unsigned char
是唯一具有固定大小的类型(机器的自然字节,通常为8位)。因此,如果你设计的是可移植性,那么这是一个安全的赌注。但是使用
unsigned int
或者甚至是
long-long
来加速这个过程并使用
size\u的
来找出每次读取的位数并不困难,尽管这样代码会变得更复杂

你应该知道,对于真正的可移植性,C++内部的任何类型都是固定的。一个无符号字符可能有9位,int可能在0到65535之间,如和answer中所述

正如user1200129所建议的,另一种选择是使用来减少所有这些不确定性。这是如果您的平台上有可用的boost。尽管对于外部库,有许多序列化库可供选择


但最重要的是,在开始优化之前,先做一些简单的事情。然后,当您开始遇到计时问题时,可以开始分析。

如果需要强制执行整数类型中的位数,则需要使用
标题。它既存在于C又存在于C++中。它定义类型,例如
uint8\u t
(8位无符号整数),保证在平台上解析为正确的类型。它还告诉其他阅读您的代码的程序员,位数很重要


如果您担心性能,可能需要使用大于8位的类型,例如
uint32\t
。但是,在读写文件时,您需要注意系统的持久性。值得注意的是,如果您有一个小端系统(例如x86,大多数都是ARM),那么32位值
0x12345678
将作为四个字节
0x78 0x56 0x34 0x12
写入文件,而如果您有一个大端系统(例如Sparc、PowerPC、Cell、某些ARM和Internet),它将被写入
0x12 0x34 0x56 0x78
。(读起来也一样)。当然,您可以使用8位类型并完全避免这个问题。

什么是无符号字节?字节是一个无符号字符。现在它有点像英语了。:)因为C中没有对
字节的定义,所以不能说它是否有符号。@Michel你把它编辑错了。您正在查找
未签名字符
。修复(星期五下午综合症)顺便问一下,您的文件有多长?真的有必要考虑优化吗?你必须改变单字节还是字节的“单位”块?@Deepak:使用int解析二进制数据只是为了解决端号问题。这取决于他想做什么操作,8个字符等于一个int操作。(x64)Deepak:
sizeof(long int)
并不总是与
sizeof(int)
相同。它肯定不在我正在输入的设置中。@Deepak:当它是相同的,那么为什么sizefo(long int)!=这里的sizeof(int)?不能保证为所有系统定义uint8。C99标准已经存在很长时间了,几乎所有的系统都有
。(我想不出一个不诚实的,它是最容易提供的一个标题)。C++等价物可能不存在,但这很容易解决。忽略我的答案,这是规则1 + 1,如果你不必使用预定义的序列化格式,就不要重新发明轮子。尽管重新发明轮子很有趣。“看,我的问题已经解决了”一个澄清的问题可能会引起更详细的建议。我不清楚这是否需要从信息到手的过度思考。是的,编程世界一开始就变得很奇怪;)对于可移植的int类型,可以使用boost integer.hpp。例如,如果需要确保获得64位有符号位,可以在不同的编译器和操作系统中使用boost::int64\t,您将始终获得所需的类型。当您需要重新解释_cast数据时,这一点尤为重要。