我有两个问题:
我有二进制文件的数据。我想通过使用read函数读取前8个字节来签名long int但我不能。你知道我怎么做的吗?
如何直接读取数据块到字符串? 我可以像上面那样阅读 例如:
ifstream is;
is.open ("test.txt", ios::binary );
string str ;
is. read ( str.c_str, 40 ) ; // 40 bytes should be read
答案 0 :(得分:3)
我想通过使用read函数读取前8个字节来签名long int但我不能。你知道我怎么能这样做吗?
不要认为long
足够宽,通常不是。但long long
保证至少为8字节宽:
long long x;
is.read(static_cast<char *>(&x), 8);
请注意,由于整数大小和字节序的变化,这仍然非常难以移植。
至于你的第二个问题,试试
char buf[41];
is.read(buf, 40);
// check for errors
buf[40] = '\0';
std::string str(buf);
或更安全
char buf[41];
is.get(buf, sizeof(buf), '\0');
std::string str(buf);
答案 1 :(得分:0)
我确定你的意思是将8个字节转换为64位整数,而且有多种方法可以实现这一目标。一种方法是使用union
:
union char_long {
char chars[8];
uint64_t n;
};
// Extract 8 bytes and combine into a 64-bit number by using the
// internals of the union structure.
char_long rand_num;
for(int i = 0; i < 8; i++) {
rand_num.chars[i] = in.get(); // `in` is the istream.
}
现在rand_num.n
将存储整数,以便您可以访问它。
至于第二个问题。读入字节并将它们分配给字符串:
const int len = 5; // Some amount.
char *buf = new char[len];
ifstream in("/path/to/file", ios::binary);
in.read(buf, len);
string str;
str.assign(buf);
delete[] buf;
答案 2 :(得分:0)
您可能会担心代码和数据的可移植性:如果您在各种计算机之间交换二进制文件,二进制数据将被视为垃圾(例如,由于字节顺序和字大小差异)。如果您只在已编写二进制数据的同一台机器上读取二进制数据,则可以。
另一个问题,特别是当数据庞大和/或成本高昂时,就代码库的演变而言是健壮的。例如,如果您阅读二进制结构,并且必须将其中一个字段的类型从int
(或int32_t
)更改为long
(或int64_t
)您的二进制数据文件是无用的(除非您编写特定的转换例程)。如果生成二进制文件成本很高(例如需要实验设备,或者需要昂贵的计算,那么创建它)可能会遇到麻烦。
这就是使用结构化文本格式(不是灵丹妙药,但有用)或数据库管理系统的原因。结构化文本格式包括XML(非常复杂),Json(非常简单)和Yaml(XML和Json之间的复杂性和功能)。文本格式更容易调试(您可以在编辑器中查看它们)。有几个免费的库来处理这些数据格式。数据库通常或多或少是关系型的,基于Sql。有几个免费的DBMS软件(例如PostGresQL或MySQL)。
考虑您可能感兴趣的二进制文件(在各种机器之间)的可移植性 serialization种技术,格式(XDR,Asn1)和图书馆(例如S11n等)。
如果需要考虑空间或带宽,您可能还会考虑compressing您的文字数据。