Mentre la risposta di derpface è decisamente corretta, restituisce spesso risultati imprevisti. Il motivo è che, almeno sul mio sistema operativo (Mac OSX 10.9.5), molti editor di testo terminano i loro file con un carattere di "fine linea".
Per esempio, quando ho aperto vim, digitare solo il singolo carattere 'a' (senza ritorno), e salvare, il file verrà ora contiene (in esadecimale):
61 0A
dove 61 è la lettera 'a' e 0A è un carattere di fine riga.
Ciò significa che il codice di derpface restituirà una stringa vuota su tutti i file creati da tale editor di testo.
Mentre posso certamente immaginare casi in cui un file terminato con un 'end line' dovrebbe restituire la stringa vuota, penso che ignorare l'ultimo carattere 'end line' sarebbe più appropriato quando si ha a che fare con file di testo normali; se il file è terminato da un carattere 'end line', lo ignoriamo correttamente, e se il file non viene terminato da un carattere 'end line' non è necessario controllarlo.
Il mio codice per ignorare l'ultimo carattere del file di input è:
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
int main() {
std::string result = "";
std::ifstream fin("test.txt");
if(fin.is_open()) {
fin.seekg(0,std::ios_base::end); //Start at end of file
char ch = ' '; //Init ch not equal to '\n'
while(ch != '\n'){
fin.seekg(-2,std::ios_base::cur); //Two steps back, this means we
//will NOT check the last character
if((int)fin.tellg() <= 0){ //If passed the start of the file,
fin.seekg(0); //this is the start of the line
break;
}
fin.get(ch); //Check the next character
}
std::getline(fin,result);
fin.close();
std::cout << "final line length: " << result.size() <<std::endl;
std::cout << "final line character codes: ";
for(size_t i =0; i<result.size(); i++){
std::cout << std::hex << (int)result[i] << " ";
}
std::cout << std::endl;
std::cout << "final line: " << result <<std::endl;
}
return 0;
}
quale uscita sarà:
final line length: 1
final line character codes: 61
final line: a
Sul 'un' singolo file.
MODIFICA: la riga if((int)fin.tellg() <= 0){
causa effettivamente problemi se il file è troppo grande (> 2 GB), perché tellg non restituisce solo il numero di caratteri dall'inizio del file (tellg() function give wrong size of file?). Potrebbe essere meglio testare separatamente l'inizio del file fin.tellg()==tellgValueForStartOfFile
e per gli errori fin.tellg()==-1
. Il tellgValueForStartOfFile
è probabilmente 0, ma un modo migliore di fare in modo probabilmente sarebbe:
fin.seekg (0, is.beg);
tellgValueForStartOfFile = fin.tellg();
C'è * qualcosa * che è forte nel fatto che qualcuno * costantemente * modifica il file? Come definiresti "robusto" in quella circostanza? –
@ user788171 dovresti essere in grado di cercare fino alla fine e scansionare all'indietro per un terminatore di riga. Probabilmente ti suggerirei di non usare qui un file raw, comunque, dal momento che sembra più che tu voglia un pipe. – oldrinb