Если вы хотите просто взять двоичные данные в подарок в обратном порядке, независимо от его значения, ваш код в порядке.
Некоторые рекомендации:
Вы должны затем открыть поток в binary
для последовательности accross платформы (т.е. избежать, что новая строка преобразуется в двойной перевод строки на платформах, таких как окна, которые кодируют как 0x0d,0x0a
).
Вы также можете рассмотреть возможность использования в цикле относительного положения к текущему, чтобы перемещаться в обратном направлении, а не всегда заканчивать и перестраивать себя с абсолютной позиции с конца.
Здесь доработан код:
ifstream fileA("test.txt", ios::binary); // binary data because binary revert
fileA.seekg(-1, ios::end); // position on last char to be read
char ch;
for (; fileA.get(ch); fileA.seekg(-2, ios::cur)) // try to read and rewind.
std::cout << ch;
Ваш код, однако, не в состоянии прочитать соответствующие UTF8 закодированных файлы, так как многобайтовые последовательности будут mecanically revereted, и их вернулись версия недействительна UTF8 :
- Это не проблема, если в вашем файле есть только символы ASCII.
- Если UTF8 консистенция является проблемой для вас, вы могли бы рассмотреть очень простой обходного пути: если вы читаете символ
u
, для которого (u & 0xC0) == 0x80
, вы должны прочитать все предыдущие символы, пока это условие не становится ложным, и выход из группы байтов (от 2 до 8) в правильном порядке.
Вот как это сделать:
... // If UTF-8 must be processed correctly
fileA.seekg(-1, ios::end);
char ch, buft[9]{},*p;
bool mb=false;
for (; fileA.get(ch); fileA.seekg(-2, ios::cur))
{
if (mb) { // if we are already processing a multibyte sequence
if ((ch & 0xC0) == 0x80 && p!=buft) // still another byte ?
*--p=ch;
else {
cout <<ch<<p; // if no other output the current leading char followed by the multibyte encoding that we've identified
mb=false; // and multibyte processing is then finished
}
}
else if ((ch & 0xC0) == 0x80) { // if a new multibyte sequence is identified
mb =true; // start its processing
buft[7]=ch;
p=buft+7;
}
else std::cout << ch; // normal chars ar procesed as before.
}
Здесь в runnable demo.
Последний вопрос: удаление последнего байта из входного потока зависит от операционной системы. Вы должны посмотреть на this SO question, чтобы получить ответы на вопрос о том, как это сделать в linux/posix и windows.
«Это работает»: интересно, пытались ли вы использовать файл utf8? – Christophe
Ну, блокнот говорит, что он находится в UTF 8 без спецификации. это имеет значение ? коды работают для чтения ... @Christophe – Noam
Проблема в вашем подходе - многобайтовые символы UTF8. Возьмем пример небольшого pi: его кодировка UTF8 равна 0xCF 0x80. Если вы пишете на своем выходе 0x80 0xCF, это недопустимая последовательность UTF8. Но та же проблема возникает из-за окон для любого текста: '\ n' закодирован в файлах как 0x0D 0x0A. При чтении в текстовом режиме вы получите только «\ n» при чтении этой последовательности. Но с вашим подходом вы сначала позиционируете на 0x0A, вы получите «\ n», а затем вы поместите на 0x0D, который будет считан как «\ n» снова (потому что за ним следует 0x0A). Таким образом, вы будете удваивать каждую новую строку. – Christophe