Ergebnis 1 bis 4 von 4

Thema: ifstream >> operator

  1. #1
    Forum Guru
    Registriert seit
    04.04.2005
    Beiträge
    4.139
    Danke
    0
    Bekam 0 mal "Danke" in 0 Postings

    Standard ifstream >> operator

    Hi

    C++ kann ja nicht so schwer sein, dachte ich mir...

    Ich versuche 2 short ints aus einer Datei in eine Variable einzulesen.
    Dies möchte nicht funktionieren, aus mir unerklärlichen Gründen.

    Ich verwende den >> Operator
    http://www.cplusplus.com/reference/iostream/istream/operator>>/

    Die auszulesende Datei fängt so an (Hex)
    Code:
    00 01 00 05 ...
    Mein Code (man achte auf die comments )
    Code:
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    void help() {
            cerr << "you need to specify the filename of the cache file!" << endl;
            cerr << "$ ./progname filename" << endl << endl;
    }
    
    int main(int argc, const char* argv[]) {
            if (argc < 2) {
                    help();
                    return 0;
            }
    
            cout << "cache file: " << argv[1] << endl;
    
            ifstream file;
            file.open(argv[1], ios_base::binary | ios_base::in); // ohne openmode probiert... kein unterschied
    
            if (!file || !file.good()) {
                    cerr << "ERROR: can not read file" << endl;
                    return 0;
            }
    // seekg auf 0, beg bringt auch nichts
            cout << "get point position: " << file.tellg() << endl; // INFO ist 0
    
            int short dbVersion;
            int short dbNumEntries;
    
            file >> dbVersion >> dbNumEntries;
    
            // get pointer (tellg) ist auf -1!!!!!
    
            cout << "Database Version: " << dbVersion << endl;
            cout << "Database Entries: " << dbNumEntries << endl;
    
            cout <<  endl;
    }
    http://pastebin.com/Spwsju8h (Mit Syntax Highlighting)

    Version sollte 1 sein, Entries 5
    Ausgegeben wird aber 0 und 0

    Nach den >> Operatoren ist der get pointer (tellg) komischerweise auf -1.


    Ist nur zu Lernzwecken.
    Was ich probiere einzulesen sind location cache files von android.

    Das ganze habe ich in Java Problemlos hinbekommen
    https://github.com/rrelmy/LocationCa...abase.java#L39

    Wie funktioniert das möglichst einfach in C++?
    Achtung: Dies ist ein alter Thread im HTML und Webmaster Forum
    Diese Diskussion ist älter als 90 Tage. Die darin enthaltenen Informationen sind möglicherweise nicht mehr aktuell. Erstelle bitte zu deiner Frage ein neues Thema im Forum !!!!!
    Facebook Gruppe: Böses Encoding

  2. #2
    Forum Guru Avatar von The User
    Registriert seit
    28.10.2007
    Ort
    Zwischen Pazifik und Atlantik...
    Beiträge
    4.044
    Danke
    0
    Bekam 0 mal "Danke" in 0 Postings

    Standard AW: ifstream >> operator

    Das heißt das ist eine Binärdatei, richtig? Tja, die >> Operatoren sind aber für das Einlesen von Text, und wenn da keine gültige Zahl steht, gibts natürlich einen Fehler und er geht nach -1. Du musst schon get() und Konsorten benutzen, um an einzelne Bytes oder shorts einzulesen.

    PS:
    Kannst dir ja flott ne Unterklasse machen, die den operator>> für short, int etc. binär macht, also einfach get() benutzt.
    Geändert von The User (29.07.2011 um 14:06 Uhr)

  3. #3
    Forum Guru
    Themenstarter

    Registriert seit
    04.04.2005
    Beiträge
    4.139
    Danke
    0
    Bekam 0 mal "Danke" in 0 Postings

    Standard AW: ifstream >> operator

    es könnte auch einfacher sein
    aber es wahr lehrreich

    1. problem
    einlesen des short
    Code:
    short dbVersion;
    file.read((char*)&dbVersion, sizeof dbVersion);
    funktioniert so, ABER das file is als big-endian aufgebaut, daher hatte ich zahlen wie 256 anstatt 1 und 1280 anstatt 5.
    mein system ist little endian


    2. konvertieren von big endian zu little
    Code:
    int is_big_endian()
    {
        int num = 1;
        return *(char *)&num != 1;
    }
    
    /**
     * converts big endian short to host endianess short
     * NOP if big endian system
     *
     * big to host endian
     */
    short b2he(short value)
    {
            if (is_big_endian()) {
                    return value;
            }
    
            unsigned char byte1, byte2;
            byte1 = value & 255;
            byte2 = (value >> 8) & 255;
    
            return (byte1 << 8) + byte2;
    }
    Code:
    dbVersion = b2he(dbVersion);

    P.S. Wieso funktioniert das Forum nicht mit Chrome?
    Ist ja nervig...
    Facebook Gruppe: Böses Encoding

  4. #4
    Forum Guru Avatar von The User
    Registriert seit
    28.10.2007
    Ort
    Zwischen Pazifik und Atlantik...
    Beiträge
    4.044
    Danke
    0
    Bekam 0 mal "Danke" in 0 Postings

    Standard AW: ifstream >> operator

    Ich nutze einfach die BBCodes…

    Code:
    #include <fstream>
    #include <iostream>
    #include <type_traits>
    
    using namespace std;
    
    class my_binary_be_ifstream : public ifstream
    {
    public:
        typedef my_binary_be_ifstream self;
    private:
        template<typename T, size_t toshift>
        struct read_int
        {
            static void exec(self& me, T& x);
        };
        template<typename T, bool isint>
        struct read_value
        {
            static void exec(self& me, T& x);
        };
    public:
        template<typename T>
        self& operator>>(T& x)
        {
            read_value<T, is_integral<T>::value>::exec(*this, x);
            return *this;
        }
    };
    
    template<typename T>
    struct my_binary_be_ifstream::read_value<T, true>
    {
        static void exec(my_binary_be_ifstream& me, T& x)
        {
            x = 0;
            read_int<T, sizeof(T)>::exec(me, x);
        }
    };
    
    template<typename T, bool b>
    void my_binary_be_ifstream::read_value<T, b>::exec(my_binary_be_ifstream& me, T& x)
    {
        (ifstream&)(me) >> x;
    }
    
    template<typename T>
    struct my_binary_be_ifstream::read_int<T, 0>
    {
        static void exec(my_binary_be_ifstream&, T&)
        {
        }
    };
    
    template<typename T, size_t toshift>
    void my_binary_be_ifstream::read_int<T, toshift>::exec(my_binary_be_ifstream& me, T& x)
    {
        x += T(me.get()) << (toshift-1) * 8;
        read_int<T, toshift - 1>::exec(me, x);
    }
    
    int main()
    {
        my_binary_be_ifstream in;
        in.open("binary_ifstream_test.txt", ios::in);
        short x;
        in >> x;
        cout << x << endl;
        string s;
        in >> s;
        cout << s << endl;
    }
    Ungetestet…

    PS:
    Big Endian ist bescheuert.

    PPS:
    Habs getestet und Fehler korrigiert, hatte mal wieder vergessen, dass man Funktions-Templates ja nicht partiell spezialisieren darf. Das liest jetzt alle Integer-Typen als BE-binär ein, und alle sonstigen als normalen Text. Wenn du noch Floats oder ähnliches lesen willst, musst du die Bedingung ändern, und schauen, dass das mit dem Einlesen richtig gemacht wird (Floats etwa machen ja normalerweise keine Shifts mit).
    Geändert von The User (31.07.2011 um 09:57 Uhr)

Ähnliche Themen

  1. Hab ich einen Fehler mit dem ifstream
    Von minder im Forum Forum für alle anderen Programmiersprachen
    Antworten: 7
    Letzter Beitrag: 08.12.2008, 11:36
  2. enum operator<
    Von The User im Forum Forum für alle anderen Programmiersprachen
    Antworten: 2
    Letzter Beitrag: 01.06.2008, 22:29
  3. operator= für double.operator= double
    Von The User im Forum Forum für alle anderen Programmiersprachen
    Antworten: 5
    Letzter Beitrag: 21.04.2008, 23:02
  4. Klasentemplate - operator[]
    Von The User im Forum Forum für alle anderen Programmiersprachen
    Antworten: 0
    Letzter Beitrag: 06.04.2008, 14:48
  5. Oder Operator
    Von Haacon im Forum Forum für alle anderen Programmiersprachen
    Antworten: 2
    Letzter Beitrag: 22.07.2007, 23:56

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •