簡體   English   中英

C ++從文件流中讀取unsigned char

[英]C++ reading unsigned char from file stream

我想從二進制文件中讀取無符號字節。 所以我寫了下面的代碼。

#include <iostream>
#include <fstream>
#include <vector>
#include <istream>

std::string filename("file");
size_t bytesAvailable = 128;
size_t toRead = 128;

std::basic_ifstream<unsigned char> inf(filename.c_str(), std::ios_base::in | std::ios_base::binary) ;
if (inF.good())
{
    std::vector<unsigned char> 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_traits<char>
std::char_traits<wchar_t>

流和字符串使用這些特征來計算各種各樣的東西,比如EOF值,一系列字符的比較,字符到int的擴展以及這些東西。

如果你實例化一個像流

std::basic_ifstream<unsigned char>

您必須確保流可以使用相應的字符特征特化,並且此特化確實可以執行有用的操作。 此外,流使用facet進行實際格式化和讀取數字。 同樣,您必須手動提供這些特化。 該標准甚至不要求實現具有主模板的完整定義。 所以你也可以得到一個編譯錯誤:

錯誤:無法實例化特化std :: char_traits。

我會使用ifstream (這是一個basic_ifstream<char> ),然后去讀取vector<char> 解釋向量中的數據時,您仍可以在以后將它們轉換為unsigned char

不要使用basic_ifstream,因為它需要專門化。

使用靜態緩沖區:

linux ~ $ cat test_read.cpp
#include <fstream>
#include <iostream>
#include <vector>
#include <string>


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 <fstream>
#include <iostream>
#include <vector>
#include <string>


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<unsigned char> 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 <fstream>
#include <iostream>
#include <vector>
#include <string>


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<unsigned char> 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

一種更簡單的方法:

#include <fstream>
#include <vector>

using namespace std;


int main()
{
    vector<unsigned char> bytes;
    ifstream file1("main1.cpp", ios_base::in | ios_base::binary);
    unsigned char ch = file1.get();
    while (file1.good())
    {
        bytes.push_back(ch);
        ch = file1.get();
    }
    size_t size = bytes.size();
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM