Модераторы: xvr

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Посимвольный проход по UTF-8 строке 
:(
    Опции темы
proc_maker
Дата 9.2.2007, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 11.11.2006

Репутация: 1
Всего: 1



Здавствуйте эксперты!

Как сделать посимволное чтение в юникодовской строке, т.е. что-то типа

const char *strUtf8="........";
for (int i=0; i<strlen(strUtf8); i++)
{
   char c=strUtf8[i];
}

но для многобайтной строк в UTF-8?

Спасибо!
PM MAIL ICQ Skype   Вверх
bsa
Дата 10.2.2007, 23:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 16
Всего: 196



А в чем собственно проблема?
Код
#include <iostream>
#include <cstring>
using namespace std;
main()
{
        const char *text = "очень простая utf8 строка";
        int n = strlen(text);
        for(int i = 0; i < n; ++i)
                std::cout << text[i];
        std::cout << std::endl;
}
выводит именно "очень простая utf8 строка".
PM   Вверх
V.A.KeRneL
  Дата 11.2.2007, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vadim A. Kazantsev
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 3.12.2006
Где: Moscow, Russia

Репутация: нет
Всего: 14



bsa, проблема в Юникоде! smile
Мне тоже тема интересна. Может кто-то из гуру, например MAKCim, поможет ньюбам...



--------------------
«C'est un pense-creux d'ici. C'est le meilleur et le plus irascible homme du monde...» © Ф.М. Достоевский, «Бесы»
---/)/)---(\.../)---(\(\
--(':'=)---(=';'=)---(=':')
(")(")..)-(").--.(")-(..(")(")

PM MAIL IM ICQ AOL YIM MSN   Вверх
MAKCim
Дата 11.2.2007, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207





--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
MAKCim
Дата 12.2.2007, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



Код

static void get_utf8(const char *str) {
    unsigned char bits, index;
    while (*str) {
        __asm__("1: shlb $1, %1\nincb %0\njc 1b" : "=r" (bits) : "r" (*str), "0" (0));
        char __utf_array[bits];
        index = bits;
        str += bits;
        while (--bits) __utf_array[bits] = 0x80 | (*(str - (index - bits)) & ~(~0 << 6));
        bits = index;
        if (index > 1) bits = index + 1;
        *__utf_array = *(str - index) & ~(~0 << (8 - bits));
/* [__utf_array ... __utf_array + index ) содержит то, что надо */
    }
}


Это сообщение отредактировал(а) MAKCim - 12.2.2007, 10:36


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
V.A.KeRneL
  Дата 12.2.2007, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vadim A. Kazantsev
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 3.12.2006
Где: Moscow, Russia

Репутация: нет
Всего: 14



Ну, что я говорил! Тхеньк ю вери мач, MAKCimsmile 
proc_maker, имхо, тему мона прикрыть, ещё разок от себя поблагодарив отзывчевого эксперта за помощь.



--------------------
«C'est un pense-creux d'ici. C'est le meilleur et le plus irascible homme du monde...» © Ф.М. Достоевский, «Бесы»
---/)/)---(\.../)---(\(\
--(':'=)---(=';'=)---(=':')
(")(")..)-(").--.(")-(..(")(")

PM MAIL IM ICQ AOL YIM MSN   Вверх
proc_maker
Дата 16.2.2007, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 11.11.2006

Репутация: 1
Всего: 1



Цитата(bsa @ 10.2.2007,  23:03)
А в чем собственно проблема?
Код
#include <iostream>
#include <cstring>
using namespace std;
main()
{
        const char *text = "очень простая utf8 строка";
        int n = strlen(text);
        for(int i = 0; i < n; ++i)
                std::cout << text[i];
        std::cout << std::endl;
}
выводит именно "очень простая utf8 строка".

А проблема именно в том что strlen(txt) != COUNT_BYTES_IN_LINE потому как каждый символ может кодироваться одним-тремя байтами. Это раз. да и цеплять для такой операции iostream мне не хотелось бы

Добавлено @ 12:32 
Цитата(MAKCim @ 12.2.2007,  10:25)
Код

static void get_utf8(const char *str) {
    unsigned char bits, index;
    while (*str) {
        __asm__("1: shlb $1, %1\nincb %0\njc 1b" : "=r" (bits) : "r" (*str), "0" (0));
        char __utf_array[bits];
        index = bits;
        str += bits;
        while (--bits) __utf_array[bits] = 0x80 | (*(str - (index - bits)) & ~(~0 << 6));
        bits = index;
        if (index > 1) bits = index + 1;
        *__utf_array = *(str - index) & ~(~0 << (8 - bits));
/* [__utf_array ... __utf_array + index ) содержит то, что надо */
    }
}

ООО, да. помоему это именно то что надо, если я правильно понимаю, выполнив вместо

/* [__utf_array ... __utf_array + index ) содержит то, что надо */

чтото типа

char *symbol=new char [bits+1];
bzero(symbol, bits+1);
memcpy(symbol, __utf_array, bits);
printf("%s\n", symbol);
...

я увижу (при str=="строка")
с
т
р
о
к
а

Правильно я понял?

PS. Огромное спасибо!! Простите что сразу не отреагировал на Ваш ответ, работа... Ееще раз thanks!
PM MAIL ICQ Skype   Вверх
chaos
Дата 16.2.2007, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Серийный программист
****


Профиль
Группа: Завсегдатай
Сообщений: 2979
Регистрация: 7.7.2004
Где: Екатеринбург

Репутация: 3
Всего: 44



а чем wstring не нравиться?
PM WWW   Вверх
MAKCim
Дата 16.2.2007, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



proc_maker
прочитай сначала то, что в ссылке выше


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
proc_maker
Дата 16.2.2007, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 11.11.2006

Репутация: 1
Всего: 1



Цитата(MAKCim @ 16.2.2007,  16:22)
proc_maker
прочитай сначала то, что в ссылке выше

Что именно?
PM MAIL ICQ Skype   Вверх
MAKCim
Дата 16.2.2007, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



Цитата(proc_maker @  16.2.2007,  17:35 Найти цитируемый пост)
Что именно? 

все
и потом посмотри принцип преобразования и что лежит в __utf_array

Это сообщение отредактировал(а) MAKCim - 16.2.2007, 20:58


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
georain
Дата 1.5.2008, 00:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Объясните пожалуйста.

Вот я написал:
Код

char * str = "Русский текст, возможно в каком-то Unicode, но я не знаю";

Что лежит в коде или в памяти программы?
Если там лежит строка в формате utf8(или другой Unicode), то каким образом осуществляется переход от старых компиляторов которые ничего об Unicode не знают? Если там не Unicode то как вообще чего происходит? smile

Как разные компиляторы ведут себя с этим, вроде Unicode даже в стандарте ещё пока нет?

Далее, я пишу строку:
Код

cout << str << endl;

Как эта строка выводится на экран физически? Кто реализует функциональность Unicode, библиотеки типа glibc или моя программа?

И последний вопрос, я пишу:
Код

char str[256];
cin >> str;

Ввожу в консоли: "hello" или "привет", что будет в str (в случае не utf8 и utf8 консоли)?

Ничего не понимаю, и не нашёл ничего нормального, а по ссылке выше: "Our servers are on a coffee break." smile

P.S. И вот ещё вопрос, например хочу ввести utf8 строку, передать её по сети (или пропустить через буфер) и вывести на экран, это всё можно сделать манипулируя только указателями (без преобразований)? Опять же тут вопрос, что лежит в строке.

P.S.S. И зачем wstring? Всё на сегодня вопросы все.  smile 

Это сообщение отредактировал(а) georain - 1.5.2008, 00:28
PM MAIL   Вверх
MHz
Дата 1.5.2008, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 1.5.2008

Репутация: нет
Всего: нет



ты по-моему совсем запутался... Unicode - кодировка латиницы, русская кирилица вместе с ее буквами НЕ UNICODE. лично у меня русские буквы в UTF-8.
Цитата

Что лежит в коде или в памяти программы?

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

#include <stdio.h>

int main(int argc, char *argv[]){
     char stack;
     printf("Stack begins at %p\n", &stack);
     return 0;
}

указывает на вершину стека(хотя это можно и на асме реализовать, но теряется кроссплатформенность), но это так, для примера.
Цитата

Если там лежит строка в формате utf8(или другой Unicode), то каким образом осуществляется переход от старых компиляторов которые ничего об Unicode не знают?

я думал старые компиляторы уникод только и знали...
Цитата

Как эта строка выводится на экран физически? Кто реализует функциональность Unicode, библиотеки типа glibc или моя программа?

Попробуй сделать так и посмотри что произойдет:
#include <unistd.h>

int main(int argc, char *argv[]){
     write(STDOUT_FILENO, "Hello!\n", 8);
     return 0;
}
Цитата

Ввожу в консоли: "hello" или "привет", что будет в str (в случае не utf8 и utf8 консоли)?

в случае utf-8 {'H', 'e', 'l', 'l', 'o', '\n', '\0', 0, 0, 0, 0, 0, ...., 0} или {'П', 'р', 'и', 'в', 'е','т', '\n', '\0', 0, 0, 0, 0, 0, ...., 0}, иначе - зависит от кодировки.
Цитата

P.S. И вот ещё вопрос, например хочу ввести utf8 строку, передать её по сети (или пропустить через буфер) и вывести на экран, это всё можно сделать манипулируя только указателями (без преобразований)? Опять же тут вопрос, что лежит в строке.

в принципе можно передавать строку от начала до конца, без преобразований, но известив клиента о кодировке строки.
Цитата

P.S.S. И зачем wstring? Всё на сегодня вопросы все.

специально для не-Unicode строк.
PM MAIL   Вверх
georain
Дата 1.5.2008, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Цитата(MHz @  1.5.2008,  11:25 Найти цитируемый пост)
Unicode - кодировка латиницы, русская кирилица вместе с ее буквами НЕ UNICODE. лично у меня русские буквы в UTF-8.

Либо я совсем запутался, либо MHz, совсем запутался.
UTF-8 это не Unicode?

Эксперты плиз!
PM MAIL   Вверх
JackYF
Дата 1.5.2008, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 3
Всего: 162



Цитата(MHz @  1.5.2008,  10:25 Найти цитируемый пост)
Unicode - кодировка латиницы

Не верно.

UTF-8 - один из вариантов юникода, самый распространённый. А вообще википедия рулит.

Компиляторы о юникоде не знают ровно ничего в случае не-wchar_t.
Если собираешься обрабатывать юникодные строки посимвольно, используй wchar_t. Либо можешь воспользовать QString из QtCore smile



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
bsa
Дата 5.5.2008, 00:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 16
Всего: 196



Цитата(georain @ 1.5.2008,  00:08)
Объясните пожалуйста.

Вот я написал:
Код

char * str = "Русский текст, возможно в каком-то Unicode, но я не знаю";

Что лежит в коде или в памяти программы?

Как уже заметил JackYF, компилятор ничего не знает про юникод и кодировки вообще (если, конечно, wchar_t не используется). Именно поэтому он в код пихает буквально то, что находится в кавычках. А кодировка текста в кавычках полностью зависит от кодировки исходного файла (*.cpp, например). Именно поэтому, если кодировка файла cp1251, то и в исполняемом файле весь текст будет в кодировке cp1251.
PM   Вверх
Ken
Дата 11.5.2008, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 31.3.2007

Репутация: нет
Всего: 4



Код

std::wstring fromUtf8 (const char *str)
{
    std::wstring result;
    int bytes = 0;
    int code;

    while (true)
    {
        int ch = static_cast <unsigned char> (*str++);
        if (ch == 0)
            break;
        // Первый байт последовательности?
        if (bytes == 0)
        {
            // Вычисляем количество байтов для текущего символа
            // т.е. количество 1 в старших битах
            while (true)
            {
                ch <<= 1;
                if (ch < 256) break;
                ch &= 0xff;
                ++bytes;
            }
            // bytes содержит количество байтов
            // Восстанавливаем первый байт без служебных единиц в старших битах
            code = ch >> (bytes + 1);
        }
        else
        {
            // Учитываем след. байт в unicode
            code = (code << 6) + (ch & 0x3f);
        }

        if (bytes > 0)
            --bytes;
        // Все коды учтены?
        if (bytes == 0)
            // Добавляем символ к строке
            result += code;
    }
    return result;
}


Это сообщение отредактировал(а) Ken - 18.5.2008, 08:46
PM MAIL   Вверх
NAYakaSL
Дата 12.5.2008, 04:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 9.5.2008

Репутация: нет
Всего: нет



Согласен, w_char_t тут рулит, вот только код когда будет такой:
Код

w_char_t *st = L"А вот здесь уже свободно может располагаться строка с символами, что кодируются 2мя байтами, т.е. UTF8";


Как работать с, пока еще не очень распространенной UTF16, я хз. smile
PM MAIL   Вверх
Ken
Дата 12.5.2008, 06:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 31.3.2007

Репутация: нет
Всего: 4



Цитата(NAYakaSL @ 12.5.2008,  04:49)
Как работать с, пока еще не очень распространенной UTF16, я хз. smile

Для кодов символов от 0x0000 до 0xFFFF (исключая интервал 0xD800–0xDFFF - они не являются символами по стандарту) кодировка UTF16 совпадает с обычным юникодом. Символы большинство языков, в том числе и русского языка находится в этом интервале. Смотрите:

http://ru.wikipedia.org/wiki/UTF-16

PM MAIL   Вверх
null56
Дата 14.5.2008, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 4
Всего: 12



За что отвечает вот эта строчка....
Код

 __asm__("1: shlb $1, %1\nincb %0\njc 1b" : "=r" (bits) : "r" (*str), "0" (0));


Объясните пожалуйста, что это за асемовский макрос или как?
PM MAIL   Вверх
MAKCim
Дата 15.5.2008, 09:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



Цитата(null56 @  14.5.2008,  21:24 Найти цитируемый пост)
Объясните пожалуйста, что это за асемовский макрос или как? 

количество единичных подряд идущих разрядов начиная со старшего


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Jorjio
Дата 24.5.2008, 20:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 20.5.2008
Где: г. Москва

Репутация: нет
Всего: нет



Сталкивался в своё время со строками в библиотеках KDeveloper (QT1.45....2.30).

Если поможет
в QT1.45 всё путем QString однобайтовый и сним можно обращатся как с любым массивом символов. 
в QT2.30 всё не путем QString Unicode-овый, под него в этой версии библиотеки был создан класс QChar. 
Т.е. в QT2.30 QString это массив QChar. Для того чтобы использовать стандартную однобайтовую строку используется класс QСString как массив char соответственно.

Ну а вообще я сталкивался только с 1и2 байтовыми строками и если надо идти именно по индексу ну так в чем проблема иди по 1-му или 2 байта, смотря конечно для чего это.

PM MAIL ICQ Skype   Вверх
JackYF
Дата 25.5.2008, 00:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 3
Всего: 162



Цитата(Jorjio @  24.5.2008,  19:21 Найти цитируемый пост)
QT1.45

Цитата(Jorjio @  24.5.2008,  19:21 Найти цитируемый пост)
QT2.30

На дворе уж Qt 4.4, где ты эти ископаемые нашёл? smile



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Jorjio
Дата 25.5.2008, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 20.5.2008
Где: г. Москва

Репутация: нет
Всего: нет



JackYF: Да ты чё Qt 4.4 smile . Вот это скорость.

А я в QT1.45 на "Hello word"-e застрял smile 
PM MAIL ICQ Skype   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.1271 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.