我想从二进制文件中读取无符号字节.所以我写了下面的代码.
#include#include #include #include std::string filename("file"); size_t bytesAvailable = 128; size_t toRead = 128; std::basic_ifstream inf(filename.c_str(), std::ios_base::in | std::ios_base::binary) ; if (inF.good()) { std::vector mDataBuffer; mDataBuffer.resize(bytesAvailable) ; inF.read(&mDataBuffer[0], toRead) ; size_t counted = inF.gcount() ; }
这导致读取始终为0字节,如计数变量所示.
网上似乎有一些引用说我需要设置语言环境才能使其正常工作.如何做到这一点对我来说并不清楚.
相同的代码使用数据类型'char'而不是'unsigned char'
上面使用unsigned char的代码似乎可以在Windows上运行,但无法在colinux Fedora 2.6.22.18中运行.
为了让它适用于linux,我需要做些什么?
C++确实只需要实现为两个版本的字符特征提供显式特化:
std::char_traitsstd::char_traits
流和字符串使用这些特征来计算各种各样的东西,比如EOF值,一系列字符的比较,字符到int的扩展以及这些东西.
如果你实例化一个像流
std::basic_ifstream
您必须确保流可以使用相应的字符特征特化,并且此特化确实可以执行有用的操作.此外,流使用facet进行实际格式化和读取数字.同样,您必须手动提供这些特化.该标准甚至不要求实现具有主模板的完整定义.所以你也可以得到一个编译错误:
错误:无法实例化特化std :: char_traits.
我会ifstream
改用(这是一个basic_ifstream
),然后去读一个vector
.解释向量中的数据时,您仍可以将它们转换为unsigned char
以后的数据.
不要使用basic_ifstream,因为它需要专门化.
使用静态缓冲区:
linux ~ $ cat test_read.cpp #include#include #include #include using namespace std; int main( void ) { string filename("file"); size_t bytesAvailable = 128; ifstream inf( filename.c_str() ); if( inf ) { unsigned char mDataBuffer[ bytesAvailable ]; inf.read( (char*)( &mDataBuffer[0] ), bytesAvailable ) ; size_t counted = inf.gcount(); cout << counted << endl; } return 0; } linux ~ $ g++ test_read.cpp linux ~ $ echo "123456" > file linux ~ $ ./a.out 7
使用矢量:
linux ~ $ cat test_read.cpp #include#include #include #include using namespace std; int main( void ) { string filename("file"); size_t bytesAvailable = 128; size_t toRead = 128; ifstream inf( filename.c_str() ); if( inf ) { vector mDataBuffer; mDataBuffer.resize( bytesAvailable ) ; inf.read( (char*)( &mDataBuffer[0]), toRead ) ; size_t counted = inf.gcount(); cout << counted << " size=" << mDataBuffer.size() << endl; mDataBuffer.resize( counted ) ; cout << counted << " size=" << mDataBuffer.size() << endl; } return 0; } linux ~ $ g++ test_read.cpp -Wall -o test_read linux ~ $ ./test_read 7 size=128 7 size=7
在第一次通话中使用reserve而不是调整大小:
linux ~ $ cat test_read.cpp #include#include #include #include using namespace std; int main( void ) { string filename("file"); size_t bytesAvailable = 128; size_t toRead = 128; ifstream inf( filename.c_str() ); if( inf ) { vector mDataBuffer; mDataBuffer.reserve( bytesAvailable ) ; inf.read( (char*)( &mDataBuffer[0]), toRead ) ; size_t counted = inf.gcount(); cout << counted << " size=" << mDataBuffer.size() << endl; mDataBuffer.resize( counted ) ; cout << counted << " size=" << mDataBuffer.size() << endl; } return 0; } linux ~ $ g++ test_read.cpp -Wall -o test_read linux ~ $ ./test_read 7 size=0 7 size=7
如您所见,如果没有调用.resize(计数),向量的大小将是错误的.请记住这一点.使用cast是常见的,请参阅cppReference