Чтение символов Юникода из файла в C ++ - PullRequest
2 голосов
/ 07 января 2012

Я хочу читать файл Unicode (UTF-8) символ за символом, но я не знаю, как читать из файла один за другим символ.

Может кто-нибудь сказать мне, как это сделать?

Ответы [ 4 ]

3 голосов
/ 07 января 2012

UTF-8 совместим с ASCII, поэтому вы можете читать файл UTF-8 так же, как файл ASCII. C ++ способ прочитать весь файл в строку:

#include <iostream>
#include <string>
#include <fstream>

std::ifstream fs("my_file.txt");
std::string content((std::istreambuf_iterator<char>(fs)), std::istreambuf_iterator<char>());

Результирующая строка содержит символы, соответствующие байту UTF-8. Вы могли бы пройти через это так:

for (std::string::iterator i = content.begin(); i != content.end(); ++i) {
    char nextChar = *i;
    // do stuff here.
}

Кроме того, вы можете открыть файл в двоичном режиме , а затем перемещаться по каждому байту следующим образом:

std::ifstream fs("my_file.txt", std::ifstream::binary);
if (fs.is_open()) {
    char nextChar;
    while (fs.good()) {
        fs >> nextChar;
        // do stuff here.
    }
}

Если вы хотите делать более сложные вещи, я советую взглянуть на Qt . Я нашел это довольно полезным для такого рода вещей. По крайней мере, менее болезненный, чем ICU , для выполнения в основном практических дел.

QFile file;
if (file.open("my_file.text") {
    QTextStream in(&file);
    in.setCodec("UTF-8")
    QString contents = in.readAll();

    return;
}
3 голосов
/ 07 января 2012

Сначала посмотрите, как UTF-8 кодирует символы: http://en.wikipedia.org/wiki/UTF-8#Description

Каждый символ Unicode кодируется в один или несколько байтов UTF-8. После того, как вы прочитали первый следующий байт в файле, согласно этой таблице:

(строка 1) Если старший бит равен 0 (char & 0x80 == 0), у вас есть ваш персонаж.

(строка 2) Если три старших значащих бита равны 110 (char & 0xE0 == 0xc0), необходимо прочитать другой байт, а биты 4,3,2 первого байта UTF-8 (110YYYyy) составляют первый байт символа Unicode (00000YYY) и двух младших битов с 6 младшими битами следующего байта (10xxxxxx) составляют второй байт символа Unicode (yyxxxxxx); Вы можете сделать битовую арифметику легко используя сдвиги и логические операторы C / C ++:

UnicodeByte1 =   (UTF8Byte1 << 3) & 0xE0;
UnicodeByte2 = ( (UTF8Byte1 << 6) & 0xC0 ) | (UTF8Byte2 & 0x3F);

И так далее ...

Звучит немного сложно, но это не сложно, если вы знаете, как изменить биты, чтобы поместить их в нужное место для декодирования строки UTF-8.

1 голос
/ 22 октября 2014

В теории в strlib.h есть функция mblen, оболочка которой возвращает длину многобайтового символа. Но в моем случае он возвращает -1 для первого байта многобайтового символа и продолжает возвращаться все время. Поэтому я пишу следующее:

{
    if(i_ch == nullptr) return -1;
    int l = 0;
    char ch = *i_ch;
    int mask = 0x80;
    while(ch & mask) {
        l++;
        mask = (mask >> 1);
    }
    if (l < 4) return -1;
    return l;
}  

Это займет меньше времени, чем исследование того, как оболочка использует mblen.

0 голосов
/ 07 января 2012

попробуйте это: получите файл, а затем переберите текст, основываясь на его длине

псевдокод:

String s = file.toString();
int len = s.length();
for(int i=0; i < len; i++)
{
    String the_character = s[i].

    // TODO : Do your thing :o)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...