[C++] Numero bytes istringstream e ifstream
Ciao a tutti! Sto cercando di imparare il sistema IOS per l'input e l'output;
So che la classe ifstream permette di gestire input stream da disco , e istringstream da memoria.
Facendo alcune prove per cercare di capire come funzionano i vari metodi ho notato una cosa strana.
Ho creato un file di nome "file" su cui ho scritto : 1
Solo il numero uno senza nessuno spazio nè prima nè dopo.
Eseguendo le seguenti linee di codice:
ciò che mi appare su output è : 2
cioè il carattere "1" occupa 2 bytes??
invece se faccio :
mi appare "1" come credo che debba accadere.
Come mai questo coomportamento? Mi sembra che se eseguo le operazioni coi metodi di ifstream su un file esterno mi venga aggiunto sempre un byte.
Cosa mi sto perdendo?
Grazie
So che la classe ifstream permette di gestire input stream da disco , e istringstream da memoria.
Facendo alcune prove per cercare di capire come funzionano i vari metodi ho notato una cosa strana.
Ho creato un file di nome "file" su cui ho scritto : 1
Solo il numero uno senza nessuno spazio nè prima nè dopo.
Eseguendo le seguenti linee di codice:
ifstream is("file"); is.seekg(0,ios::end); cout << is.tellg() << endl;
ciò che mi appare su output è : 2
cioè il carattere "1" occupa 2 bytes??
invece se faccio :
istringstream is("1"); is.seekg(0,ios::end); cout << is.tellg() << endl;
mi appare "1" come credo che debba accadere.
Come mai questo coomportamento? Mi sembra che se eseguo le operazioni coi metodi di ifstream su un file esterno mi venga aggiunto sempre un byte.
Cosa mi sto perdendo?
Grazie
Risposte
Mostra il codice di scrittura su file. Hai provato ad aprire il file in un editor di testo (o addirittura un editor esadecimale) per vederne il contenuto?
Su file ho scritto io dalla tastiera , ho scritto su gedit "1" e ho chiuso. Ho fatto svariati tentativi, ma il risultato è sempre lo stesso, sembra ci sia un byte in più quando leggo su file.
Visto che ci sono chiedo un'altra cosa.
Sulle note del mio professore viene detto che utilizzando il metodo getline (o get) , se si supera la fine dello stream viene attivata una segnalazione di errore , e non è più permesso compiere operazioni in lettura, a meno che non si esegua il metodo clear().
Ma facendo una prova con questo codice:
la segnalazione non mi appare, e ho superato abbondantemente la fine dello stream visto che è una parola sola cioè "topolinia"..
non sono andato a capo, quindi getline non avrebbe dovuto interpretare di fermarsi(perchè getline ha un terzo argomento ,di default '\n', che gli farebbe stoppare l'estrazione nel caso in cui fosse presente nel file da leggere), quindi non capisco..
Visto che ci sono chiedo un'altra cosa.
Sulle note del mio professore viene detto che utilizzando il metodo getline (o get) , se si supera la fine dello stream viene attivata una segnalazione di errore , e non è più permesso compiere operazioni in lettura, a meno che non si esegua il metodo clear().
Ma facendo una prova con questo codice:
ifstream is("file"); char *c = new char[10]; is.getline(c,90); if(!is){cout << " errore \n"; }
la segnalazione non mi appare, e ho superato abbondantemente la fine dello stream visto che è una parola sola cioè "topolinia"..
non sono andato a capo, quindi getline non avrebbe dovuto interpretare di fermarsi(perchè getline ha un terzo argomento ,di default '\n', che gli farebbe stoppare l'estrazione nel caso in cui fosse presente nel file da leggere), quindi non capisco..
Se hai inserito il numero a mano direttamente nel file ci possono essere tantissime ragioni per cui i byte sono due e non uno solo. Dipende molto dalle impostazioni del tuo editor di testo e dalla codifica usata per salvare il file.
Per quanto riguarda il secondo problema, ogni stream si ferma quando incontra la fine dello stream. Non è detto che venga generata una eccezione in questo caso e quindi non è detto che venga mostrato alcun errore in esecuzione. Piuttosto non dovresti essere in grado semplicemente di leggere un'altra riga ma questo è ovvio.
Ma visto quello che hai detto riguardo alla presenza di due caratteri e non uno nel punto precedente, penso che un carattere di a capo possa essere effettivamente stato scritto automaticamente dall'editor. Per cui non è detto che sia stato raggiunta la fine del file con quella lettura.
Infine, cosa più grave, il secondo argomento di getline dovrebbe essere la lunghezza del buffer e non un valore a caso!! In generale, per leggere una riga di lunghezza sconosciuta di un file, la funzione getline che estrae una std::string è più semplice da usare.
Per quanto riguarda il secondo problema, ogni stream si ferma quando incontra la fine dello stream. Non è detto che venga generata una eccezione in questo caso e quindi non è detto che venga mostrato alcun errore in esecuzione. Piuttosto non dovresti essere in grado semplicemente di leggere un'altra riga ma questo è ovvio.
Ma visto quello che hai detto riguardo alla presenza di due caratteri e non uno nel punto precedente, penso che un carattere di a capo possa essere effettivamente stato scritto automaticamente dall'editor. Per cui non è detto che sia stato raggiunta la fine del file con quella lettura.
Infine, cosa più grave, il secondo argomento di getline dovrebbe essere la lunghezza del buffer e non un valore a caso!! In generale, per leggere una riga di lunghezza sconosciuta di un file, la funzione getline che estrae una std::string è più semplice da usare.
Il secondo argomento non dovrebbe essere il numero do bytes da leggere?
Comunque la cosa che mi lascia perplesso è che anche dopo aver "sforato" , posso comunque continuare a leggere, senza bisogno di utilizzare clear(); a questo punto può darsi che gedit metta il carattere a capo, questo forse spiegherebbe anche il byte in più.
Ma ci sarebbe un modo per verificarlo?
Comunque la cosa che mi lascia perplesso è che anche dopo aver "sforato" , posso comunque continuare a leggere, senza bisogno di utilizzare clear(); a questo punto può darsi che gedit metta il carattere a capo, questo forse spiegherebbe anche il byte in più.
Ma ci sarebbe un modo per verificarlo?
Non ricordo le opzioni di gedit, ma puoi semplicemente usare un debugger per vedere quali byte vengono letti da un file. Oppure puoi usare un editor esadecimale.