LINUX.ORG.RU

Работа со строками в ASCII и UTF-8


0

0

Есть программа, использующая 8-битные кодировки: ASCII, KOI-8 и т.п. Требуется исправить её, чтобы понимала UTF-8. Возникли 2 вопроса:

1. Правильно ли я понимаю, что функции strcat, strcmp, strcpy, strlen, strtod, strtok в современном линуксе уже поддерживают UTF?

2. Как получить n-й символ в строке? С 1-байтными просто: line[n], а как быть с переменной длиной символа? (Например, строка из русских букв с пробелами и знаками препинания.)

Заранее спасибо?

★★★★★

Ответ на: комментарий от root66

>Скажем, если в массиве встретился "А", вместо него вывести "а". С численным представлением однобайтных символов такой алгоритм пишется в три строки. А с двумя байтами на символ что-то ни как :-(

И охота вам иметься со всякой бякой?

1. Прога заточена исключительно под русский? Нет? Тогда почему только 2 байта?

2. Забить на обработку utf-8 - использовать её только для хранения/передачи, обрабатывать ucs-32

3. Взять приличную уникодную библиотеку - да, монстр, но каждый символ знает свой верхний/нижний регистр - и не париться

yyk ★★★★★
()
Ответ на: комментарий от root66

>Вывести уже введённый с клавиатуры символ так действительно можно. Но сгенерировать свой собственный по номеру символа - нет.

Почему? Для UCS-2 диапазон задаётся достаточно просто, для UTF-8 несколько сложнее, но решаемо: А-Я — от 0xd0 0x90 до 0xd0 0xaf, а-п — от 0xd0 0xb0 до 0xd0 0xbf, р-я — от 0xd1 0x80 до 0xd1 0x8f, Ё — 0xd0 0x81, ё — 0xd1 0x91. Читай как получается UTF-8 из UCS-2.

> Скажем, если в массиве встретился "А", вместо него вывести "а". С численным представлением однобайтных символов такой алгоритм пишется в три строки. А с двумя байтами на символ что-то ни как :-(

Уже сказали: преобразовать в UCS, сменить регистр, преобразовать в UTF. Или воспользоваться одной из перечисленных выше библиотек (я их не осилил). "Простым" преобразованием регистра через установку/снятие бита лучше не пользоваться, т.к. это создаст геморрой при адаптации программы при очередной смене локали по умолчанию :) Лучше вызывать соответствующие функции libc.

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

Вот здесь, видимо, проблема и кроется. Требуется решить задачу, сохраняя начальные условия, а именно: кодировка UTF-8, набор библиотек - стандартный, из промышленного дистрибутива (RHEL, SLES), т.е. <wchar.h>, <wctype.h> и т.п., но не более. Корень зла - переносимость и длительный жизненный цикл приложений.

Да и сомнительно, что этого набора не хватит, чтобы всего лишь забрать из stdin, прогнать через несложный анализатор кодов символов да и выплюнуть в stdout несколько символов, пусть и, местами, двухбайтных.

Вопрос: чем ? Есть надежда, что mbtowc/mbstowcs могут здесь как-то пригодиться и копать, IMHO, следует в сторону wide character.

К своему огромному сожалению ни одного примера такого рода в открытых источниках найти не удаётся :-( Не пользуется ни кто что-ли простыми стандартными функциями ?

Хотя бы типа такого: char c1, c2, c; c1 = 0xd0; // (старший байт) c2 = 0xb0; //(младший байт) c = ;// как-то уложить старший и младший байты в один мультибайт, после чего

putchar(c); // вывели "а" и выдохнули с облегчением :-)

Очевидная примитивность обсуждаемой задачи ни как не вяжется с обнаруженной сложностью её реализации на практике.

Так как на счёт идей ?

root66
()
Ответ на: комментарий от root66

> набор библиотек - стандартный, из промышленного дистрибутива (RHEL, SLES), т.е. <wchar.h>, <wctype.h> и т.п., но не более.

Чего ты людям голову морочишь? Если не можешь использовать ничего другого кроме wchar, пользуйся wchar.

> как-то уложить старший и младший байты в один мультибайт, после чего putchar(c);


Не надо страдать херней. Обрабатывай wchar и его же выводи.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Покорнейше благодарю за справедливую критику и конструктивные предложения! Заморочившись сам неизбежно морочу остальных в слабой надежде найти решение простое и эффективное, как молоток. На то оно и комьюнити, IMHO.

По поводу:

>Не надо страдать херней. Обрабатывай wchar и его же выводи.

Как на счёт фрагмента кода в студию ? Спасибо!

root66
()
Ответ на: комментарий от question4

При правильном использовании glib можно писать кроссплатформенные приложения! Так что приобретаешь гораздо больше, нежели просто работу с юникод.

hibou ★★★★★
()
Ответ на: комментарий от root66
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>

int main(int argc, char** argv)
{
    wchar_t ch;
    while(1) {
        ch = fgetwchar();
        fputwchar(ch);
    }
    return 0;
}

Пожалуйста.

LamerOk ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.