Хотя ответ derpface определенно верен, он часто возвращает неожиданные результаты. Причина этого заключается в том, что, по крайней мере, в моей операционной системе (Mac OSX 10.9.5) многие текстовые редакторы завершают свои файлы символом «конечной линии».
Например, когда я открываю Vim, введите только один символ «а» (без возврата), и сохраните файл теперь будет содержать (в шестнадцатеричном виде):
61 0A
Где 61 это буква 'a' и 0A - символ конца строки.
Это означает, что код derpface вернет пустую строку для всех файлов, созданных таким текстовым редактором.
Хотя я могу, конечно, представить случаи, когда файл, заканчивающийся «конечной линией», должен возвращать пустую строку, я думаю, что игнорирование последнего символа «конечной строки» было бы более уместным при работе с обычными текстовыми файлами; если файл заканчивается символом «конечной линии», мы его должным образом игнорируем, и если файл не заканчивается символом «конечной линии», нам не нужно его проверять.
Мой код для игнорирования последнего символа входного файла:
#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;
}
Что будет:
final line length: 1
final line character codes: 61
final line: a
На одном 'а' файла.
EDIT: строка if((int)fin.tellg() <= 0){
действительно вызывает проблемы, если файл слишком большой (> 2 ГБ), потому что tellg не просто возвращает количество символов с начала файла (tellg() function give wrong size of file?). Может быть, лучше провести отдельную проверку для начала файла fin.tellg()==tellgValueForStartOfFile
и для ошибок fin.tellg()==-1
. tellgValueForStartOfFile
вероятно 0, но лучший способ убедиться, вероятно, будет:
fin.seekg (0, is.beg);
tellgValueForStartOfFile = fin.tellg();
Есть ли что-либо *, что является прочным в факте кого-то * постоянно * изменение файла? Как бы вы даже определили «здравый» в этом обстоятельстве? –
@ user788171 вы должны быть в состоянии искать до конца и отсканировать назад для терминатора линии. Однако я бы предположил, что вы не используете здесь необработанный файл, поскольку это похоже на то, что вы хотите использовать канал. – oldrinb