позиция ifstream в c ++ - PullRequest
       25

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

0 голосов
/ 23 октября 2009

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

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

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

Ответы [ 5 ]

2 голосов
/ 23 октября 2009

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

2 голосов
/ 23 октября 2009

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

1 голос
/ 23 октября 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.

0 голосов
/ 23 октября 2009

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

ifstream::seekg()
ifstream::teellg()
0 голосов
/ 23 октября 2009

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

...