Si bien la respuesta por derpface es definitivamente correcta, a menudo devuelve resultados inesperados. La razón de esto es que, al menos en mi sistema operativo (Mac OSX 10.9.5), muchos editores de texto terminan sus archivos con un carácter de 'línea final'.
Por ejemplo, cuando abro vim, escriba sólo el único carácter 'a' (sin retorno), y guardar, el archivo será ahora contiene (en hexadecimal):
61 0A
Donde 61 es la letra 'a' y 0A es un carácter de fin de línea.
Esto significa que el código por derpface devolverá una cadena vacía en todos los archivos creados por dicho editor de texto.
Si bien puedo imaginar casos en que un archivo terminado con una 'línea final' debe devolver la cadena vacía, creo que ignorar el último carácter 'línea final' sería más apropiado cuando se trata de archivos de texto regulares; si el archivo termina con un carácter de 'línea final', lo ignoramos adecuadamente, y si el archivo no termina con un carácter de 'línea final', no es necesario que lo verifiquemos.
Mi código para ignorar el último carácter del archivo de entrada es:
#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;
}
Cuál sería:
final line length: 1
final line character codes: 61
final line: a
En la 'a' fila india.
EDITAR: La línea if((int)fin.tellg() <= 0){
en realidad causa problemas si el archivo es demasiado grande (> 2 GB), ya que no solo devuelve el número de caracteres desde el inicio del archivo (tellg() function give wrong size of file?). Puede ser mejor probar por separado para el inicio del archivo fin.tellg()==tellgValueForStartOfFile
y para los errores fin.tellg()==-1
. El tellgValueForStartOfFile
es probablemente 0, pero una mejor manera de asegurarse de que probablemente sería:
fin.seekg (0, is.beg);
tellgValueForStartOfFile = fin.tellg();
¿Hay * algo * que sea robusto en el hecho de que alguien * constantemente * modifique el archivo? ¿Cómo definirías "robusto" en esa circunstancia? –
@ user788171 debe poder buscar hasta el final y buscar un terminador de línea hacia atrás. Sin embargo, probablemente te sugiero que no uses un archivo en bruto, ya que suena más como si quisieras un tubo. – oldrinb