Zu wenig Daten aus Datei eingelesen.



  • Hallo!

    Ich versuche, ein 37 KB großes Wave-File aus einem istream zu lesen. Nach 28000 Aufrufen von get() erhalte ich allerdings schon ein eof und hab überhaupt keine Ahnung, woran das liegen kann. Eigentlich müßte get() doch jedes Mal genau ein Byte auslesen, und das Programm sollte also auf 37000 Aufrufe kommen. Wenn ich über das eof hinweglese, kommen auch tatsächlich keine Daten mehr.
    Ein Java-Programm, das eigentlich genau das gleiche tut, liest korrekt die ganzen 37 KB ein. An der Datei selbst liegt es also nicht. Die eingelesenen und wieder in eine Datei zurückgeschriebenen Daten sind größtenteils dieselben, allerdings treten mitten in der Datei, bei manchen negativen Integern, Abweichungen auf, die mir irgendwie rätselhaft sind. Hat irgendwer 'ne Idee dazu?
    Hier der Quelltextausschnitt:

    while (!wavefile.eof()) {
    signed int test;
    char lbit;
    lbit = wavefile.get();
    char hbit;

    hbit = wavefile.get();
    test = (signed int) hbit;
    test <<= 8;
    test += lbit;
    signal[index] = test;
    dataout << test <<"\n";
    cout << index++ << "\n";´
    }
    }

    Tschöö,
    Anja



  • Vielleicht hast Du die Datei nicht im Binärmodus geöffnet.



  • Hallo!

    Danke, das war's! 🙂 Vielleicht sollte ich demnächst genauer lesen, bevor ich irgendwas zusammenhacke... Nachdem Du's hier geschrieben hast, hab' ich das mit den Binärdateien auch im Stroustrup gefunden. Muß ich bislang irgendwie hartnäckig überlesen haben... Aber ich bin vermutlich eh irreversibel Java-geschädigt! 😃

    Tschüssi,
    Anja



  • Kann es sein, dass du immer ein (oder sogar zwei) EOF einliest und in ein char packst?
    get liefert einen int, keinen char.

    edit: Hab mich unklar ausgedrückt. Ich glaube, deine Schleife läuft einmal zu oft. istream::eof() liefert erst dann true, wenn get bereits ein EOF eingelesen hat (AFAIK).



  • @cd9000: get() liest laut Doku genau ein Zeichen aus. Von daher bin ich davon ausgegangen, daß das wohl ein Char sein wird, aber Du hast recht, es ist ein Integer. Weißt Du, wieso? Hat das irgendeinen tieferen Sinn? 😃

    Das mit dem einen Schleifendurchlauf zuviel stimmt... War mir gestern Abend selbst noch aufgefallen, daß ich am Ende 0 einlese. Daß das Programm immer zwei Bytes auf einmal liest, ohne zwischendurch auf eof zu prüfen, ist natürlich generell auch falsch, geht hier aber, weil ich 16 Bit Wave-Daten habe, und von daher auf jeden Fall eine gerade Anzahl Bytes an Sounddaten in der Datei vorhanden sein muß.

    Immerhin, es funktioniert jetzt!

    Mal eine ganz andere Frage: Gibt's für C++ irgendwo so eine nette Dokumentation, wie die API-Doku für Java? Also eine Seite, auf der die verschieden Klassen der STL stehen und deren Methoden/Parametersignaturen/Rückgabewerte/ + kurze Erklärung? Der Stroustrup ist zwar gut und zum Lernen ideal, aber irgendwie unübersichtlich, wenn man nur 'ne Kurzreferenz sucht.

    Tschüssi,
    Anja



  • Wieso liest Du die Datei nicht auf einen Haps ein ?



  • Knuddlbaer: wie das? Die Datei besteht aus einem Hader, der variabel lang sein kann, und den man erstmal abschneiden muß und danach aus einer beliebigen Anzahl von 16 Bit-Samples, die ich zum Weiterverarbeiten in einen vector einlese. Mir fällt dazu keine einfachere Möglichkeit ein, als die Datei sequenziell auszulesen... hab' ich irgendwas übersehen?

    Tschüssi,
    Anja



  • get() liest laut Doku genau ein Zeichen aus. Von daher bin ich davon ausgegangen, daß das wohl ein Char sein wird, aber Du hast recht, es ist ein Integer. Weißt Du, wieso? Hat das irgendeinen tieferen Sinn?

    Kaputte C-Api. get muss neben allen möglichen Zeichen ja auch irgendwie eof liefern könnnen. eof kann nun aber schlecht ein gültiges Zeichen sein, sonst könnte man ja nicht mehr unterscheiden. Also verwendet man statt char einfach int und hat damit noch ganz viel Platz für eof.
    Ich finde diese Schnittstelle so hässlich, dass ich sie mit nicht-Benutzung abstrafe. Statt

    int_type c = cin.get();
    

    schreibe ich immer:

    char c = 0;
    cin.get(c);
    

    Letzteres kann man auch schön in einer Bedingung verwenden:

    char c;
    while (cin.get(c))
    {
    balala
    }
    

    Mal eine ganz andere Frage: Gibt's für C++ irgendwo so eine nette Dokumentation, wie die API-Doku für Java? Also eine Seite, auf der die verschieden Klassen der STL stehen und deren Methoden/Parametersignaturen/Rückgabewerte/ + kurze Erklärung? Der Stroustrup ist zwar gut und zum Lernen ideal, aber irgendwie unübersichtlich, wenn man nur 'ne Kurzreferenz sucht

    Es gibt natürlich Übersichten über den Inhalt der Standardbibliothek:
    Z.B.
    http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
    http://www.sgi.com/tech/stl/


Anmelden zum Antworten