локализация в коде C/C++ (как писать)
Модератор: Модераторы разделов
локализация в коде C/C++
Писать иноязычный (кроме англоязычного) ввод-вывод в коде совсем не так просто.
И книги и статьи по C/C++ вам в этом не помогут - там везде вам скормят текстовые строки char[], или на худой конец string ... а они для ввода-вывода символов Unicode непригодны.
Вот мои краткие (пока 22 стр.) заметки на эту тему: Локализация в коде C/C++.
И архив программных кодов, иллюстрирующих описываемое.
Это не ... философствование по форумам , а выжимки из практических разработок за несколько (достаточно много) лет.
Но если кто-то подскажет ещё что-то в этом направлении ... больше проблем и вопросов возникающих, чем их решений - я буду очень признателен, и расширю текст в этом направлении.
И книги и статьи по C/C++ вам в этом не помогут - там везде вам скормят текстовые строки char[], или на худой конец string ... а они для ввода-вывода символов Unicode непригодны.
Вот мои краткие (пока 22 стр.) заметки на эту тему: Локализация в коде C/C++.
И архив программных кодов, иллюстрирующих описываемое.
Это не ... философствование по форумам , а выжимки из практических разработок за несколько (достаточно много) лет.
Но если кто-то подскажет ещё что-то в этом направлении ... больше проблем и вопросов возникающих, чем их решений - я буду очень признателен, и расширю текст в этом направлении.
Re: локализация в коде C/C++
книги и статьи по C/C++
Локализация в коде, вообще то говоря, сильно интересная тема.
Но вопросы локализации определяются не столько языком программирования, сколько а операционной системой и её настройками. Поэтому локализация на других языках, скажем Python, полностью наследуют те же принципы, и только изображаются API этого языка. В будущем, возможно, я расширю текст примерами ещё на нескольких языках программирования ... хотя это достаточно тривиально после C/C++.
Всё это порождает несколько направлений вопросов, которые интересно бы пообсуждать (в коде, разумеется ):
- сравнительно: локализация в Linux и локализация Windows ... где для кодировния Unicode используется такое представление как UTF-16, ... и живо ещё такое уродство как кодовые страницы;
- вопросы переносимости программных кодов в смысле локализации;
- обработка локализованных строк в других языках программирования, Python, Perl ... да тот же bash.
Я бы с интересом пообсуждал эти вещи ... только не с теми, кто хочет пообсуждать насколько он умён, а кто любит и умеет обсуждать и улучшать программный код.
- Bizdelnick
- Модератор
- Сообщения: 20792
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: локализация в коде C/C++
Давайте таки обсудим, насколько я умён.
Не вижу ни малейшего смысла делать в коде локализацию. Делать там надо интернационализацию, для чего существует куча готовых библиотек во главе с gettext. В чём смысл темы?
Не вижу ни малейшего смысла делать в коде локализацию. Делать там надо интернационализацию, для чего существует куча готовых библиотек во главе с gettext. В чём смысл темы?
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: локализация в коде C/C++
Не актуально.
Bizdelnick писал(а): ↑02.09.2016 13:04Не вижу ни малейшего смысла делать в коде локализацию. Делать там надо интернационализацию, для чего существует куча готовых библиотек во главе с gettext. В чём смысл темы?
Смысл темы - в программном коде. Которому (коду) иногда нужно разгребать контекст вводимых символьных строк (по ходу выполнения) на ... китайском, скажем, языке.
Но вас это не должно беспокоить или обременять...
don't worry be happy
- Bizdelnick
- Модератор
- Сообщения: 20792
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: локализация в коде C/C++
Таки причём тут локализация? Как писать код, способный обрабатывать текст в любой кодировке, — тема действительно интересная, но к локализации отношения не имеет ни разу. У меня вот русская локаль, но это не значит, что произвольная запущенная мной программа имеет право не понимать китайский ввод.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: локализация в коде C/C++
Bizdelnick писал(а): ↑02.09.2016 13:14но это не значит, что произвольная запущенная мной программа имеет право не понимать китайский язык.
Значит
- Bizdelnick
- Модератор
- Сообщения: 20792
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: локализация в коде C/C++
Все наши нынешние проблемы с локалями от того, что кто-то когда-то тоже так посчитал.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: локализация в коде C/C++
Bizdelnick писал(а): ↑02.09.2016 13:39Все наши нынешние проблемы с локалями от того, что кто-то когда-то тоже так посчитал.
Оставайтесь при ваших нынешних проблемах.
Недосуг мне дискутировать насколько вы там умны себе кажетесь...
P.S. Я это сообщение специально разместил в раздел "Программирование для начинающих" - может кому-то из начинающих программистов это покажется интересным и когда-то пригодится. Вы же, насколько я понимаю, являетесь престарелым администратором, и к этой категории никоим боком не относитьесь?
Как в песне:
В этом городе женщин,
Ищущих старость,
О чём и зачем мы станем спорить?
Re: локализация в коде C/C++
Судя по вот этой фразе:
- пишется всё это даже не взглянув на текст по ссылке, и не дав себе труда понять о каком предмете там вообще ведётся речь.
Т.е. намерением ответа изначально было не предметно обсуждать вопрос, а сознательно устроить срач.
Вполне похвальное намерение ... достойный образец для подражания юношеству.
С чем я вас и посздравляю ... Удалось!
Bizdelnick писал(а): ↑02.09.2016 13:04Делать там надо интернационализацию, для чего существует куча готовых библиотек во главе с gettext.
- пишется всё это даже не взглянув на текст по ссылке, и не дав себе труда понять о каком предмете там вообще ведётся речь.
Т.е. намерением ответа изначально было не предметно обсуждать вопрос, а сознательно устроить срач.
Вполне похвальное намерение ... достойный образец для подражания юношеству.
С чем я вас и посздравляю ... Удалось!
- Bizdelnick
- Модератор
- Сообщения: 20792
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: локализация в коде C/C++
Взглянул, почему же. Увидел кучу кириллицы в сишном коде, ужаснулся.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: локализация в коде C/C++
Бывает...
Лишь бы не перед сном.
Re: локализация в коде C/C++
По фразе
Может сложиться впечатление, что char может быть равен signed char или unsigned char, но на самом деле — то три разных типа, как по мне, стоило бы подчеркнуть.
(внаш — опечатка)
Не поможет.
1. В среде Win в wchar_t возможны суррогатные пары, а значит рассмотренный Вами ранее реверс строки, не сработает и в случае wchar_t.
2. Умляуты и т.п., которые идут как отдельный символ, но не воспринимаются пользователем как таковой. Т.е. тот же реверс сработает неправильно. Плюс, для сортировки умляуты обычно игнорируют. Упомянутая ё — лишь один из случаев из множества сортировки не в соответствием с кодом символа.
ИМХО, после пары таких велосипедов для ознакомления стоит смотреть на библиотеку ICU. Особенно, если учесть не упомянутые особенности превращения в верхний/нижний регистр, которые зависят от локали (I i для английского, но I ı и İ i для турецкого), особенности немецкой ß, и другие сюрпризы.
То ли у меня в глазах двоится…
Опечатка.
Описка.
char может представляться как знаковое или беззнаковое байтовое значение (или указываться явно: unsigned char или signed char) ... но для наших дальнейших целей это не существенно.
Может сложиться впечатление, что char может быть равен signed char или unsigned char, но на самом деле — то три разных типа, как по мне, стоило бы подчеркнуть.
Как только внаш код начинает анализировать или изменять содержимое строки, нам необходимо работать с только с локализованными строками (строками широких символов wchar_t[]).
(внаш — опечатка)
Не поможет.
1. В среде Win в wchar_t возможны суррогатные пары, а значит рассмотренный Вами ранее реверс строки, не сработает и в случае wchar_t.
2. Умляуты и т.п., которые идут как отдельный символ, но не воспринимаются пользователем как таковой. Т.е. тот же реверс сработает неправильно. Плюс, для сортировки умляуты обычно игнорируют. Упомянутая ё — лишь один из случаев из множества сортировки не в соответствием с кодом символа.
ИМХО, после пары таких велосипедов для ознакомления стоит смотреть на библиотеку ICU. Особенно, если учесть не упомянутые особенности превращения в верхний/нижний регистр, которые зависят от локали (I i для английского, но I ı и İ i для турецкого), особенности немецкой ß, и другие сюрпризы.
Так:
stdout = freopen( NULL, "w", stdout );
Или даже так, ещё проще:
stdout = freopen( NULL, "w", stdout );
То ли у меня в глазах двоится…
ptintf()
Опечатка.
// Сортировка подпоследователности. Гарантированная сложность O( n*log(n) ) в любом случае.
// Обычно сортировка в куче выполняется в 25 раз медленнее быстрой сортировки sort().
Описка.
Re: локализация в коде C/C++
В среде Win в wchar_t возможны суррогатные пары
А вот пример такйо задачи. Есть файл, в неизвестной кодировке (внутри китайский или арбский текст, например). Есть алгоритм (набор правил, программа в никс или еще хоть что-то) что гарантировано убирало бы суррогатные пары? Я их убираю алгоритмом, который не понимаю и который оставляет из 100 тысяч текстов пару суррогатных. но главное, он убирает, я текст записываю в базу с utf8, затем достаю по словам (то есть разделитель пробел) и получаю суррогатные пары, которые в постгрес блокируются.
Вопрос, что надо почитать, чтобы победить эту проблему?
зы
Ну вдруг чудеса ведь бывают, мне лучше алгоритм, так как я на паскале пишу
Re: локализация в коде C/C++
За любые такие замечания - спасибо!
NickLion писал(а): ↑02.09.2016 16:50По фразеchar может представляться как знаковое или беззнаковое байтовое значение (или указываться явно: unsigned char или signed char) ... но для наших дальнейших целей это не существенно.
Может сложиться впечатление, что char может быть равен signed char или unsigned char, но на самом деле — то три разных типа, как по мне, стоило бы подчеркнуть.
Это тонкое место, которое заслуживает отдельного рассмотрения.
Как-то мне помниться, что в разных ОС char - это либо signed char, либо unsigned char
NickLion писал(а): ↑02.09.2016 16:50Как только внаш код начинает анализировать или изменять содержимое строки, нам необходимо работать с только с локализованными строками (строками широких символов wchar_t[]).
(внаш — опечатка)
Не поможет.
1. В среде Win в wchar_t возможны суррогатные пары, а значит рассмотренный Вами ранее реверс строки, не сработает и в случае wchar_t.
2. Умляуты и т.п., которые идут как отдельный символ, но не воспринимаются пользователем как таковой. Т.е. тот же реверс сработает неправильно. Плюс, для сортировки умляуты обычно игнорируют. Упомянутая ё — лишь один из случаев из множества сортировки не в соответствием с кодом символа.
ИМХО, после пары таких велосипедов для ознакомления стоит смотреть на библиотеку ICU. Особенно, если учесть не упомянутые особенности превращения в верхний/нижний регистр, которые зависят от локали (I i для английского, но I ı и İ i для турецкого), особенности немецкой Я, и другие сюрпризы.
Как оно там в Windows я представляю в деталях слабо ... и даже проверить толком негде.
Помню только, что wchar_t там - UTF-16.
Это описка, нужно исправить.
azsx писал(а): ↑02.09.2016 17:12В среде Win в wchar_t возможны суррогатные пары
А вот пример такйо задачи. Есть файл, в неизвестной кодировке (внутри китайский или арбский текст, например). Есть алгоритм (набор правил, программа в никс или еще хоть что-то) что гарантировано убирало бы суррогатные пары? Я их убираю алгоритмом, который не понимаю и который оставляет из 100 тысяч текстов пару суррогатных. но главное, он убирает, я текст записываю в базу с utf8, затем достаю по словам (то есть разделитель пробел) и получаю суррогатные пары, которые в постгрес блокируются.
Вопрос, что надо почитать, чтобы победить эту проблему?
Хорошая проблема.
Нужно будет к ней вернуться, займёмся.
P.S. Только у меня нет вблизи никакого текста ни на китайском, ни на арабском ... ни на иврите ... да ещё содержащего суррогатные пары. Да и взять такие тексты не представляю где. Поэтому разбирать такие тонкие проблемы нужно начать с того, что подготовить тестовые тексты - и не слишком большого объёма. и содержащие требуемые артефакты.
Спасибо сказали:
Re: локализация в коде C/C++
Нужно будет к ней вернуться, займёмся.
Как решите заняться, скажите, я вам страниц проблемных накачаю и выложу.
У меня около 15 млн сайтов скачано, много обработано, но в программе проблемы с кодировками решаются отбрасыванием еще на взлете, так что придется отдельно искать.
Re: локализация в коде C/C++
Код: Выделить всё
#include <iostream>
#include <typeinfo>
void f(char)
{
std::cout << "char" << std::endl;
}
void f(signed char)
{
std::cout << "signed char" << std::endl;
}
void f(unsigned char)
{
std::cout << "unsgined char" << std::endl;
}
int main(int argc, const char *argv[])
{
char c;
signed char sc;
unsigned char uc;
std::cout << typeid(c).name() << std::endl;
std::cout << typeid(sc).name() << std::endl;
std::cout << typeid(uc).name() << std::endl;
f(c);
f(sc);
f(uc);
return 0;
}
Вывод:
Код: Выделить всё
c
a
h
char
signed char
unsgined char
т.е. и с точки зрения перегрузки и typeid — все три типа разные (что соответствует стандарту).
Re: локализация в коде C/C++
azsx писал(а): ↑02.09.2016 17:12В среде Win в wchar_t возможны суррогатные пары
А вот пример такйо задачи. Есть файл, в неизвестной кодировке (внутри китайский или арбский текст, например). Есть алгоритм (набор правил, программа в никс или еще хоть что-то) что гарантировано убирало бы суррогатные пары? Я их убираю алгоритмом, который не понимаю и который оставляет из 100 тысяч текстов пару суррогатных. но главное, он убирает, я текст записываю в базу с utf8, затем достаю по словам (то есть разделитель пробел) и получаю суррогатные пары, которые в постгрес блокируются.
Вопрос, что надо почитать, чтобы победить эту проблему?
зы
Ну вдруг чудеса ведь бывают, мне лучше алгоритм, так как я на паскале пишу
Все суррогатные пары имеют чётко обозначенные коды, можно просто выкинуть все wchar_t символы с кодами 0xD800–0xDFFF (диапазон, включающий верхние и нижние суррогаты).
Спасибо сказали:
Re: локализация в коде C/C++
символы с кодами 0xD800–0xDFFF (диапазон, включающий верхние и нижние суррогаты).
Именно так мой алгоритм и делает. Но потом, я читаю эти переменные целиком из БД в кодировке utf8, делю их по словам (как пример) и пытаюсь записать в бд в utf8. И иногда снова появляются такие пары.
Как так?
Re: локализация в коде C/C++
Стандарту чего?
Символьный тип
В общем случае размер типа char на конкретной платформе регулируется значением константы CHAR_BITS, определённой в заголовочном файле limits.h. По умолчанию и на платформах x86 она равна 8. Char может вмещать максимум один символ ASCII.
Если char определён как signed (знаковый), то его диапазон значений составляет от −128 до 127 (может быть на единицу дальше в положительную сторону, в зависимости от реализации). Если он определён как unsigned (беззнаковый), то его значения могут составлять от 0 до 255. Значение, содержащееся в этом типе, можно всегда безопасно привести к значению типа int
</usr/include/stdint.h>
Код: Выделить всё
typedef signed char int8_t;
...
typedef unsigned char uint8_t;
И всё. Никаких других определений char в C нет, и долгое время изначально, он вообще определялся как int (K&R).
Можете уже выкладывать.
Спасибо сказали:
Re: локализация в коде C/C++
Юникод и .NET
Ещё несколько лет назад считалось, что все символы «влезут» в диапазон между 0 и 216-1, а это значило, что любой символ можно представить при помощи двух байтов. К сожалению, со временем потребовалось больше символов, что привело к появлению т.н. «суррогатных пар» (surrogate pair). С ними всё стало значительно сложнее
C#, Суррогатные пары Unicode в VisualStudio
Также везде пишут, что суррогатные пары Unicode не поддерживаются только в Windows 95 и 98, а в Windows 2000, XP, Vista, 7, 8
все должно быть в порядке. Однако не работает.
Сурогатные пары - это проблемы выньдаунов, и оставим их решать выньдаунам (пока, временно, или насовсем)
Юникод
В UTF-8 не используются суррогатные пары, 4 байтов достаточно для записи любого символа юникода.
P.S. Уточним здесь только, что 4 байта - это код Unicode, UTF-32, или wchar_t (POSIX). А символ в UTF-8 (мультибайтном) может представляться от 1 до 6 байт.
Re: локализация в коде C/C++
Сурогатные пары - это проблемы выньдаунов, и оставим их решать выньдаунам (пока, временно, или насовсем)
постгрес у меня в никс запущен и пишу я в него с никс. В самом паскале проблем нет совсем. То есть внутри переменной хоть что пиши, он всё жует.
Re: локализация в коде C/C++
Что там у вас в постгрес - сказать трудно, но в любом ПО, работающем в современном Linux с UTF-8, никаких сурогатных пар ни при каких обстоятельствах возникать не может.
Потому отложим их рассмотрение ... на когда-то в будущем.
В самом классическом PASCAL от Вирта никаких Unicode, кодирования, широких символов и т.д. - не было, не упоминалось, и быть не могло, там это строка байт с предшествующей им длиной (в байтах!).
Так что в вашем случае, нужно начинать с указания той реализации PASCAL, с которым вы имеете дело + это особенность только самой реализации.
Re: локализация в коде C/C++
Так что в вашем случае, нужно начинать с указания той реализации PASCAL, с которым вы имеете дело + это особенность только самой реализации.
я же на никс форуме. fpc http://www.freepascal.org/download.var
Re: локализация в коде C/C++
azsx писал(а): ↑02.09.2016 21:14Так что в вашем случае, нужно начинать с указания той реализации PASCAL, с которым вы имеете дело + это особенность только самой реализации.
я же на никс форуме. fpc http://www.freepascal.org/download.var
И в UNIX-среде была не одна реализация ... похожая на PASCAL.
Re: локализация в коде C/C++
Не знал. Народ пишет что как-то паскаль на андруино компилирует. Я ничего в этом не понимаю, но крайне интересно.
Re: локализация в коде C/C++
Kylix
UCSD Pascal
А также:
Модула-2
Модула-3
Oberon
И это далеко не всё...
[removed]
i Уведомление от модератора SLEDopit см Производительность процессоров
Re: локализация в коде C/C++
Стандарту C++. К сожалению, Си знаю не настолько хорошо, как C++, о стандарте Си утверждать не буду. Но вот в стандарте C++ чётко оговорено:
3.9.1 Fundamental types
…
Plain char, signed char, and unsigned char are three distinct types, collectively called narrow character types. A char, a signed char, and an unsigned char occupy the same amount of storage and have the same alignment requirements (3.11); that is, they have the same object representation. For narrow character types, all bits of the object representation participate in the value representation. For unsigned narrow character types, all possible bit patterns of the value representation represent numbers. These requirements do not hold for other types. In any particular implementation, a plain char object can take on either the same values as a signed char or an unsigned char; which one is implementation-defined.
Т.е. типы разные, но char может принимать те же значения, что и signed char или unsigned char, что оставлено на усмотрение реализации.
Re: локализация в коде C/C++
NickLion писал(а): ↑02.09.2016 21:52
Стандарту C++. К сожалению, Си знаю не настолько хорошо, как C++, о стандарте Си утверждать не буду. Но вот в стандарте C++ чётко оговорено:
Т.е. типы разные, но char может принимать те же значения, что и signed char или unsigned char, что оставлено на усмотрение реализации.
Вот именно, реализации: либо так, либо этак.
Хотя стандарнты C++, во многом, это словоблулие, формалистика ... надстроенная над C, для которого C++ является только формальной надстройкой, макропроцессором ... как его первоначально и задумывал и делала Б.Страуструп.
Re: локализация в коде C/C++
Стандарт Си тоде в общем-то говорит о трёх разных типах:
Конечено, реализация должна соответстовать одному из двух вариантах, но тем не менее, они различаются, в отличие от #define или typedef алиасов.
6.2.5 Types
…
The three types char, signed char, and unsigned char are collectively called the character types. The implementation shall define char to have the same range, representation, and behavior as either signed char or unsigned char.
Конечено, реализация должна соответстовать одному из двух вариантах, но тем не менее, они различаются, в отличие от #define или typedef алиасов.
Re: локализация в коде C/C++
NickLion писал(а): ↑02.09.2016 22:01Стандарт Си тоде в общем-то говорит о трёх разных типах:
6.2.5 Types
…
The three types char, signed char, and unsigned char are collectively called the character types. The implementation shall define char to have the same range, representation, and behavior as either signed char or unsigned char.
Ну как же? вы же сами зацитировали:
as either signed char or unsigned char
ИЛИ - ИЛИ
Или вы ещё какое-то 3-е состояние можете придумать?
Но это, собственно, всё не имеет какого-то существенного значение.