Frage

Ich möchte unsigned Bytes aus einer Binärdatei lesen. Also schrieb ich den folgenden Code ein.

#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() ;
}

Dies führt zu immer 0 Bytes beim Lesen als gezählt durch die Variable gezeigt.

Es scheint Referenzen im Web zu sein, zu sagen, dass ich das Gebietsschema zu setzen, diese Arbeit zu machen. Wie dies zu tun genau das ist mir nicht klar.

Der gleiche Code funktioniert der Datentyp 'char' anstelle von 'unsigned char' mit

Der obige Code mit unsigned char scheint unter Windows zu arbeiten, aber nicht in einer colinux Fedora 2.6.22.18 ausgeführt wird.

Was muss ich tun, um es für Linux zur Arbeit?

War es hilfreich?

Lösung

C ++ funktioniert die Implementierung erfordert nur explizite Spezialisierungen für zwei Versionen von Charaktereigenschaften zu bieten:

std::char_traits<char>
std::char_traits<wchar_t>

Die Ströme und Strings verwenden diese Eigenschaften eine Vielzahl von Dingen, um herauszufinden, wie der EOF-Wert, Vergleich einer Reihe von Zeichen, ein Zeichen in einem int Verbreiterung und solche Sachen.

Wenn Sie instanziiert einen Strom wie

std::basic_ifstream<unsigned char>

Sie müssen sicherstellen, dass es eine entsprechende Charakterzug Spezialisierung ist, dass der Strom verwenden kann, und dass diese Spezialisierung nützliche Dinge tut. Darüber hinaus Ströme Facetten verwenden tatsächliche Formatierung und das Lesen von Zahlen zu tun. Ebenso müssen Sie auch manuell Spezialisierungen die bieten. Der Standard erfordert nicht einmal die Umsetzung eine vollständige Definition der primären Vorlage zu haben. So könnte man aswell einen Compiler-Fehler erhalten:

  

Fehler:. Spezialisierung std :: char_traits konnte nicht instanziiert werden

würde ich ifstream statt (das ist ein basic_ifstream<char> ist) und dann in eine vector<char> gehen und lesen. Wenn die Daten in den Vektor zu interpretieren, können Sie sie konvertieren später unsigned char.

Andere Tipps

Das basic_ifstream nicht verwenden, da es specializtion erfordert.

einen statischen Puffer verwenden:

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

unter Verwendung eines Vektors:

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 anstelle von Resize im ersten Aufruf:

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

Wie Sie sehen können, ohne dass der Anruf (gezählt) .resize, die Größe des Vektors falsch. Bitte beachten Sie dies. es ist ein gemeinsames Gießen verwenden finden Sie unter cppReference

Ein viel einfacher:

#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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top