当前位置:  开发笔记 > 编程语言 > 正文

C++从文件流中读取unsigned char

如何解决《C++从文件流中读取unsignedchar》经验,为你挑选了2个好方法。

我想从二进制文件中读取无符号字节.所以我写了下面的代码.

#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,我需要做些什么?



1> Johannes Sch..:

C++确实只需要实现为两个版本的字符特征提供显式特化:

std::char_traits
std::char_traits

流和字符串使用这些特征来计算各种各样的东西,比如EOF值,一系列字符的比较,字符到int的扩展以及这些东西.

如果你实例化一个像流

std::basic_ifstream

您必须确保流可以使用相应的字符特征特化,并且此特化确实可以执行有用的操作.此外,流使用facet进行实际格式化和读取数字.同样,您必须手动提供这些特化.该标准甚至不要求实现具有主模板的完整定义.所以你也可以得到一个编译错误:

错误:无法实例化特化std :: char_traits.

我会ifstream改用(这是一个basic_ifstream),然后去读一个vector.解释向量中的数据时,您仍可以将它们转换为unsigned char以后的数据.


我没有得到编译器错误,没有文档中的提示,没有,但是无声的失败和浪费的一天.谢谢Bjarne Stroustrup和Dennis Ritchie.

2> sfossen..:

不要使用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

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有