Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    [C++] Lettura file con istreambuf_iterator

    Devo memorizzare il contenuto di un file di testo; tra le varie soluzioni sono giunto alla seguente:

    codice:
    std::ifstream ifs("myfile.txt");
    
    std::string content( (std::istreambuf_iterator<char>(ifs) ),
                           (std::istreambuf_iterator<char>()    ) );
    Tuttavia me ne sfugge l'esatto funzionamento. Qualcuno potrebbe gentilmente spiegarmelo. Grazie.
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

  2. #2
    Uno stream di input in C++ è composto da due pezzi fondamentali: lo stream e lo streambuf.
    Lo streambuf associato ad uno stream (accessibile tramite il metodo rdbuf()) si occupa del lavoro sporco di recuperare/scrivere i byte dal/sul file/console/... su cui è aperto; in pratica, è il pezzo che si occupa dell'IO non formattato.
    Lo stream, a sua volta, chiede i byte dallo streambuf e li interpreta secondo il locale stabilito, effettuando le conversioni dai byte dello stream ai tipi che ci interessano, oltre a gestire lo stato "visibile" dello stream (i vari bit di errore ios::fail, ios::bad, ...).
    Per questo motivo, se interessano solo i dati "grezzi", la cosa più efficiente è rivolgersi direttamente allo streambuf.
    Un modo comodo per fare ciò è usare gli istreambuf_iterator: con questa classe è possibile ottenere degli iteratori associati ad uno streambuf, in modo da poterlo leggere come se si trattasse degli elementi di un qualunque container STL; il costruttore senza parametri costruisce l'iteratore speciale "EOF", a cui tutti gli iteratori associati ad uno streambuf diventano uguali quando si raggiunge la fine del file.
    Il tuo codice quindi:
    - apre un file;
    - costruisce un iteratore associato allo streambuf dello stream di input specificato (il costruttore di istreambuf_iterator accetta anche direttamente lo stream per comodità d'uso);
    - costruisce l'iteratore-eof da usare come limite per la copia;
    - richiama il costruttore di std::string che accetta due iteratori come sorgente dei caratteri per la stringa; questo acquisisce i caratteri dallo streambuf fino a quando non raggiunge la fine del file, e memorizza i caratteri così acquisiti nella stringa che sta costruendo.

    Per ulteriori informazioni su streambuf e *steambuf_iterator qui c'è un articolo ben fatto; sullo stesso concetto si basano anche gli istream_iterator/ostream_iterator, che forniscono un'interfaccia agli stream invece che agli streambuf; questo consente di caricare da file elementi di vari tipi. Ad esempio, per caricare un std::vector<int> da interi memorizzati in un file basta fare:
    codice:
    std::ifstream is("numeri.txt");
    std::vector<int> numeri(std::istream_iterator<int>(is), std::istream_iterator<int>());
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Grazie MItaly .
    Se decidessi di memorizzare invece il contenuto del file in una wstring?
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

  4. #4
    Per usare lo stesso identico metodo il file dovrebbe partire già in UTF-16 (o UTF-32 su Linux, dove i wchar_t sono di 4 byte); credo che ci sia qualche modo di usare i locale per convertire da una codifica supportata in un qualche locale alla codifica dei wchar_t, ma sinceramente non ti saprei dire come si faccia (i locale mi sono sempre stati oscuri).
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Capisco, un buon metodo alternativo per wstring quale sarebbe?
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

  6. #6
    Il file da cui leggi in che encoding è?
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.