LINUX.ORG.RU

tolower/toupper utf-8, koi8-r


0

0

Помогите с переводом строки в верхний и нижний регистры. Функция должна работать как для однобайтовой кодировке, так и для многобайтовой.

Относительно многобайтовой кодировки, проблему _временно_ решил переводом строки из кодировки nl_langinfo (CODESET) в UTF-8 и затем переводом в кодировку понимаемую glib'ом через g_utf8_get_char/g_utf8_next_char и использованием g_unichar_tolower. Получилось коряво =(, если подскажете как перевести в glib'овский юникод из nl_langinfo (CODESET), скажу спасибо. Это был вопрос номер раз.

Вопрос номер два. Если я использую nl_langinfo (CODESET) для идентификации текущей кодировки, и если кодировка nl_langinfo (CODESET) однобайтовая, то зачем мне перекодировать строку, когда я спокойно могу воспользоваться glibc'ными tolower и toupper?! И вот вопос, как определить, что кодировка nl_langinfo (CODESET) однобайтовая?

★★

Относительно первого вопроса, guint32 содержит символ в кодировке UCS-4, так что можно сразу переводить в эту кодировку минуя utf-8.

Но второй вопрос все еще актуален

ale ★★
() автор топика

Для С++
изменение кодировок iconv
изменение регистра STL

std::string Upper(const std::string p)
{
std::string ret = p;
transform(ret.begin(), ret.end(), ret.begin(), toupper);
return (ret);
}

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

>изменение кодировок iconv

вопрос не в перекодировке, она уже решена при помощи iconv некоторое время назад.

> изменение регистра STL std::string Upper(const std::string p) { std::string ret = p; transform(ret.begin(), ret.end(), ret.begin(), toupper); return (ret); }

а теперь попробуй привести к верхенму регистру строку, состоящую из кирилицы в кодировке UTF-8. (для однобайтовых кодировок с правильной локалью сработает, а вот с UTF-8 не работает)

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

теоретически если вызвать setlocale, то потом будут работать корректно остальные функции, но я с этим не работал в си, только в C++ c их stlными аналогами, в частности isalpha корректно работала для всех языков.

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

вот код (у меня системная кодировка - UTF-8), файл test.c:

#include <locale.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

int main (){
setlocale (LC_CTYPE, ENC);
char* source_str = "тест";
size_t source_str_length = strlen (source_str);
char* target_str = (char*) malloc (source_str_length + 1);
char *c = source_str;
size_t i = 0;

for (; *c != 0; c++, i++)
target_str [i] = toupper (source_str [i]);

target_str [source_str_length] = '\0';
printf ("%s\n", target_str);
}

Если запустить iconv -f utf-8 -t koi8-r test.c > test-koi8.c && gсс test-koi8.c -DENC="\"ru_RU.KOI8-R\"" && ./a.out | iconv -f koi8 -t utf-8
То выведеться "ТЕСТ".

Но если вызвать как gcc test.c -DENC="\"ru_RU.UTF-8\"" && ./a.out
То абсолютно естественно, что выводиться "тест", ибо один мультибайтный символ, просто разбивается на несколько частей.

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

wchar_t не портабельно это раз.

Два кодировка wchar_t != UTF-8 и предеться переводить из одной кодировки в другую (что сейчас и делается, но мне это не нравиться)

и три как мне узнать, что кодировка nl_langinfo (CODESET) (текущая системная кодировка) многобайтовая?

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

s/предеться/придеться/1 s/Два кодировка/Два, кодировка/1 s/и три как мне узнать/и три, как мне узнать/1

чорт, русская языка!

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

> wchar_t не портабельно это раз.

почему ж не портабельно ? wchar_t предназначено для _внутреннего_ представления широких символов (unicode) и ему ж не нужно никуда портироватся ж...

входной текст ковертируется из локальной кодировки (mb - может быть utf-8 или однобайтной) во внутреннее представление (wchar_t), обрабатывается [wcslen, towlower, fwide, wprintf, ...] и при выводе из программы - конвертируется обратно в локаль (mb)

портабельно, описано в стандартах POSIX IEEE Std 1003.1-2001, C99

Eshkin_kot ★★
()

ответа на Ваш второй вопрос не знаю, но есть предположение что единственная мультибайтная кодировка в unix'ах, которую можно поставить в качестве кодировки локали - это UTF-8 (так как она совместима с однобайтными и соответственно с стандартными системными функциями типа open(char*, ...) и т.д.). хотя я в этом не уверен...

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

Stroustroup belongs to a durka or to a pogost!

Вместо map toUpper s -

> transform(ret.begin(), ret.end(), ret.begin(), toupper);

Вот за это мы и любим С++.

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

>почему ж не портабельно ? wchar_t предназначено для _внутреннего_ представления широких символов (unicode) и ему ж не нужно никуда портироватся ж...

ну если только для внутреннего, тогда да, некуда портироваться.

>входной текст ковертируется из локальной кодировки (mb - может быть utf-8 или однобайтной) во внутреннее представление (wchar_t), обрабатывается [wcslen, towlower, fwide, wprintf, ...] и при выводе из программы - конвертируется обратно в локаль (mb)

задача стоит перевести в верхний/нижний регистры конкретные строки, которые могут быть и в KOI8-R и в UTF-8. Но двойную перекодировку из текущей в юникод и из юникода в текущую я уже делаю, а upper'ю и lower'ю с помощь glib.

Но я хотел обойтись без перекодировок, хотя бы для однобайтовых символов (к сожалению, фишка в том, что надо определить однобайтовость кодировки в runtime)

>портабельно, описано в стандартах POSIX IEEE Std 1003.1-2001, C99

я не спорю, может и написано. но увы, wchar_t виндовый != wchar_t glibc =(

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

>ответа на Ваш второй вопрос не знаю, но есть предположение что единственная мультибайтная кодировка в unix'ах, которую можно поставить в качестве кодировки локали - это UTF-8 (так как она совместима с однобайтными и соответственно с стандартными системными функциями типа open(char*, ...) и т.д.). хотя я в этом не уверен...

на мой взгляд, UTF-8 - лучший вариант представления юникодного символа, из-за совместимости c US-ASCII. Но... уже сейчас перед глазами, задача перевода из верхнего в нижний регистр и UTF-8 и UTF-16 (тот, что wchar_t в windows)

ale ★★
() автор топика
Ответ на: комментарий от php-coder

если тебе кто то даст, пидор

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