позиция ifstream в С++

Я пытаюсь написать простой декодер UTF-8 для своего задания. Я довольно новичок в C++, так что потерпите меня здесь...

Я должен определить, действительна ли кодировка или нет, и в любом случае вывести значение символа UTF-8 в шестнадцатеричном формате. Допустим, я прочитал первый байт и использовал этот первый байт для определения количества байтов в этом символе UTF8. Проблема в том, что после того, как я прочитал первый байт, у меня возникли проблемы с установкой позиции ifstream на один байт и чтением всего символа UTF-8. Я пробовал seekg() и putback(), но всегда получаю ошибку BUS или какой-то странный вывод, который не соответствует моим тестовым данным. Пожалуйста, помогите, спасибо.

Несмотря на то, что я могу использовать peek() для первого байта, мне все равно нужно прочитать следующие байты, чтобы определить, действительна ли кодировка или нет. Проблема установки обратного положения потока все еще существует.


person cplusplusNewbie    schedule 23.10.2009    source источник
comment
Это может помочь опубликовать небольшой фрагмент кода, демонстрирующий ошибку, которую вы получаете.   -  person Brian Campbell    schedule 23.10.2009


Ответы (5)


Я бы посоветовал вам использовать peek() для чтения первого байта. seekg() должен работать для перемотки назад, но ошибка BUS обычно вызывается вашим кодом, нарушающим выравнивание, что указывает на то, что вы делаете что-то еще злое в своем коде.

person McBeth    schedule 23.10.2009

Почему ты должен искать назад? Разве вы не можете просто прочитать остальную часть последовательности UTF-8, зная, сколько еще октетов вы ожидаете?

person Ates Goral    schedule 23.10.2009
comment
я должен вывести весь символ в шестнадцатеричном значении. - person cplusplusNewbie; 23.10.2009
comment
Итак, вы уже получили первый байт. Прочтите остальное и выведите все. Я не понимаю, почему вам нужно искать обратно. - person Ates Goral; 23.10.2009

Я бы прочитал следующий байт напрямую и добавил его к тому, что получил. Как сказал Атес Горал. ИМХО чище.

В любом случае, вы можете переместить указатель потока, используя seekg():

char byte = 0;
unsigned  int character = 0; // on every usage
ifstream file("test.txt", ios::binary);

file.get(byte);
......
file.seekg(-1, ios::cur); // cur == current position
file.get(
    reinterpret_cast<char*>(&character),
    numberOfBytesAndNullTerminator);

cout << hex << character;

Обратите внимание, что get() во втором случае пишет '\0' в конце character. Таким образом, вы должны указать необходимое количество байтов, включая нулевой терминатор. Итак, если вы хотите прочитать два байта ==> numberOfBytesAndNullTerminator = 3.

person AraK    schedule 23.10.2009

Я не знаю, почему вам нужно вернуть символ обратно, но istream::unget() или istream::putback() должны делать то, что вы хотите. Найдите их в документации вашего компилятора.

person jmucchiello    schedule 23.10.2009

пожалуйста, посмотрите:

ifstream::seekg()
ifstream::teellg()
person Maciek    schedule 23.10.2009