Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.139.82.23] |
|
Сообщ.
#1
,
|
|
|
Здравствуйте, Господа!
Длительное время не занимался писаниной, погрязнув в административке, но пришло время вспомнить кодинг. Сейчас в планах создание многопоточного сервера приложений. Данный демон будет крутиться на Debian и служить некоторой прослойкой между PHP кодом и БД. Будут и еще дополнительные возможности. Пока, я планирую, что он должен быть на UTF-8. Так же уже вырисовывается, что различных настроек демона должно быть до фига. Демон должен получать URL, его парсить, обрабатывать и отправлять серверу БД. Вот тут и начались проблемы. 1. Я увяз в кодировке. Не понимаю, как работать с UTF-8. Как работать с однобайтовой кодировкой (win-1251, koi-8 & etc) я представляю хорошо. А вот как работать с UTF-8 не могу понять. Тем более, что придется производить посимвольную обработку строк. И как тут быть? Набрел на wchar_t, но не получается. #include <stdio.h> #include <string.h> #include <ctype.h> #include <wchar.h> wchar_t * buf = "чертовщина"; int main(void) { int lenght = wcslen(buf); int i = 0; printf("buf = %s\nlenght = %d\n", buf, lenght); for(i = 0; i < lenght; i += 1) { printf("buf[%d] = %c\n", i, buf[i]); } return 0; } Посимвольный вывод выдает хрень. К тому же gcc ругается: warning: initialization from incompatible pointer type wchar_t * buf = "чертовщина"; В чем тут дело? Как посимвольно работать с UTF-8? 2. Посоветуйте не тяжелые библиотеки или куски кода, котрые бы декодировали и парсили URL? 3. Посоветуйте не тяжелый парсер текстового файла (конфига) На текущий момент основной вопрос с кодировкой. Парсеры, конечно, тот еще геморрой, но реализуется не сложно. Однако лучше не изобретать велосипед и использовать чьи-то наработки. |
Сообщ.
#2
,
|
|
|
Цитата А зачем так сложно, писать на С многопоточный сервер приложений? Не проще ли взять какой-нибуть Go и забыть про проблемы с UTF-8 ?Сейчас в планах создание многопоточного сервера приложений По теме, вот этот список смотрели? |
Сообщ.
#3
,
|
|
|
Цитата HighMan @ Преобразовать в wchar_t. Лучше если wchar_t будет 32-битный.Как посимвольно работать с UTF-8? Go, думается, именно так и поступает. |
Сообщ.
#4
,
|
|
|
Цитата HighMan @ служить некоторой прослойкой между PHP кодом и БД Цитата HighMan @ Демон должен получать URL, его парсить, обрабатывать и отправлять серверу БД Зачем двойной парсинг URL? Пусть PHP скрипт парсит, а данные на обработку в демон отдает в каком нить типа JSON-формате. Этот формат и дебажить удобно, и лаконичнее он того же XML. И, уверен, обработчиков JSON можно найти на выбор. Цитата HighMan @ Посимвольный вывод выдает хрень. Исходный код пиши в UTF8 без BOM (тут почитай) Добавлено Цитата HighMan @ Как посимвольно работать с UTF-8? На выбор несколько вариантов либ |
Сообщ.
#5
,
|
|
|
Цитата А зачем так сложно, писать на С многопоточный сервер приложений? Не проще ли взять какой-нибуть Go и забыть про проблемы с UTF-8 ? Если хочешь сделать хорошо, то сделай сам! Это правило работает. Всегда! И в моем демоне будут насованы дополнительные возможности. Цитата Преобразовать в wchar_t. Лучше если wchar_t будет 32-битный. Go, думается, именно так и поступает. Можно поподробнее? Дело в том, что до сих пор я с кодировками не сталкивался. Писал под винду (Win1251). Цитата Зачем двойной парсинг URL? Пусть PHP скрипт парсит, а данные на обработку в демон отдает в каком нить типа JSON-формате. Этот формат и дебажить удобно, и лаконичнее он того же XML. И, уверен, обработчиков JSON можно найти на выбор. РНР будет посылать данные из формы на демон. Тот будет производить некие манипуляции, переформатировать и отправлять БД. Далее, по необходимости, принимает ответ от БД, преобразует в json и отправляет РНР. Идея в том, что бы РНР код НИКАК не имел возможности общаться с БД, минуя демон. Цитата Исходный код пиши в UTF8 без BOM (тут почитай) Вроде, в Linux, в терминалке так и пишет. Я только не очень понимаю, в чем разница для gcc? Но обязательно почитаю. Спасибо! Цитата На выбор несколько вариантов либ Большое спасибо. Но... Я хочу понять как самому с UTF-8 работать. char * buf = "жопа"; for(I = 0; I < strlen(buf); I ++) printf("%c", buf[i]); Это отлично работает для однобайтовых кодировок. Я хочу схожий способ для UTF-8 Я правильно понимаю, что основная проблема работы с UTF-8 это разный "размер" буквы? Например, латинские символы "весят" 1 байт, а русские буквы 2 байта. Бредовая идея, если честно. Может есть смысл помучаться с какой-то кодировкой, которая ВСЕМ символам выделяет 2 или 4 байта. Кстати, это какие кодировки? Цитата Кодировка БД PostgreSQL и locale PostgreSQL поддерживает только общую для всех баз кластера кодировку, которая должна совпадать с локальной кодировкой (Настройка переменных локализации в Linux), иначе не будут работать строковые функции сортировки, upper/lower и т.п. Локаль общая для всех процессов сервера - соответственно он не может создать две базы в разных кодировках - кодировка всегда одна для всего сервера и всех его БД. Посмотреть кодировку сервера (show server_encoding) и клиента(show client_encoding): Эту инфу нарыл на просторах интернета. Грустно. Именно PostgreSQL и будет выступать в качестве сервера БД. Получается, что только UTF-8 и никаких гвоздей. |
Сообщ.
#6
,
|
|
|
Цитата HighMan @ char * buf = "жопа"; for(I = 0; I < strlen(buf); I ++) printf("%c", buf[i]); Это отлично работает для однобайтовых кодировок. Я хочу схожий способ для UTF-8 Вот "это" не будет работать ни для какой кодировки. Тут ошибка с индексом. --- Именно для UTF-8 этот алгоритм будет работать правильно, поскольку UTF-8 "родная" для Linux. Можешь сам попробовать. Если исходник будет в другой кодировке, на экране будут кракозябры. |
Сообщ.
#7
,
|
|
|
Цитата HighMan @ Я хочу понять как самому с UTF-8 работать. А почитай тут. Цитата HighMan @ в чем разница для gcc? Если код написан в кодировке UTF-8, компилятор и константу видит в представлении UTF-8. Иначе желательно обозначать явно через префикс, типа L"a wide string literal" Но лучче почитать текущий/последний стандарт Ц++, будет вернее. Написал по наитию |
Сообщ.
#8
,
|
|
|
Цитата Вот "это" не будет работать ни для какой кодировки. Тут ошибка с индексом. Вы имеете в виду, заглавную и прописную "i"? Тут вкралась ашипка при наборе. Разумеется, везде просто "i". Дело в том, что printf выводит на экран кракозябы. Если же printf("%s", buf) то выводит то что нужно. У меня не получается разбить строку на массив символов, а как раз это мне и нужно. |
Сообщ.
#9
,
|
|
|
Цитата ЫукпШ @ UTF-8 "родная" для Linux. Чуть-чуть не так ))) Для Линупса, да и для многих остальных *nix систем отдельного (самодостаточного) понятия "кодировка" или "кодовая страница" - не существует. Там это сделано более правильно и интегрированно - используется понятие "локаль" (locale), которая задается параметрами окружения LC_*. Туда входит и знакогенератор, и способ сортировки, и отображение дат, валют, ... Но! Для UTF-8 обязательно указывается своя кодовая страница,например, en_US.UTF-8, ru_RU.UTF-8 и т.д. "Родная" - по фэншую локаль ТОЛЬКО для пользовательского окружения!!! Для рута родная - LC_ALL="C" (однобайтовая). Это дает гарантию однозначного отображения чисто английского интерфейса командной строки, как бы не "падали" прочие "национальные красивости". Вот так - немного точнее |
Сообщ.
#10
,
|
|
|
Цитата А почитай тут. Жаль, что на форуме матершина не приветствуется. Я бы выразил свое отношение! Получается, что прямого способа работы с UTF-8 нет. В PHP худо-бедно реализовано, а в С нет. Что-то я впадаю в уныние. Пока я не знаю с какой стороны подойти к проблеме. Неужели придется плюнуть на UTF-8 и делать в однобайтной кодировке? Переводить в UTF-8 в другие кодировки (16 || 32)? Не думаю, что это выход. Уже прочел, что они работают еще кривее. |
Сообщ.
#11
,
|
|
|
Цитата HighMan @ Получается, что прямого способа работы с UTF-8 нет. Цитата JoeUser @ Исходный код пиши в UTF8 без BOM Ну или конвертируй в utf-8 программно. Добавлено Куда уж прямее-то? |
Сообщ.
#12
,
|
|
|
Цитата HighMan @ Жаль, что на форуме матершина не приветствуется. Я бы выразил свое отношение! Код: #include <iostream> #include <codecvt> #include <locale> int main() { std::u32string S = U"Жěěěра, не кепишуй!"; std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> cnv; for(const auto &c:S) std::cout << cnv.to_bytes(c) << std::endl; return 0; } Добавлено HighMan, UTF-8 кодирование - не панацея. Достоинство одно - компактность представления (соотв. и хранения). Но если тебе нужна скорость доступа, то лучше использовать - широкие символы равной размерности. Тогда доступ к n-му символу вычисляется смещением (а не сканом, как для UTF-8). |
Сообщ.
#13
,
|
|
|
Цитата HighMan @ Дело в том, что printf выводит на экран кракозябы. Если же printf("%s", buf) то выводит то что нужно. У меня не получается разбить строку на массив символов, а как раз это мне и нужно. я попробовал, это не так. --- Кроме того, для работы непосредственно с кодировкой UTF-8 вариант существует. Для этого нужно работать исключительно со строками (вместо отдельных символов). Поскольку двухбайтовый символ в char не поместится, а в стороку - никаких проблем. Значит при распарсивании/модификации можно воспользоваться исключительно операциями со строками и всё получится. Насколько это дешевле и удобнее чем преобразования UTF-8 <-> UTF-16 не знаю, не пробовал. Вот и попробуй. --- У тебя уже 2 варианта решения проблемы. |
Сообщ.
#14
,
|
|
|
Цитата Исходный код пиши в UTF8 без BOM Я пока, писал все в mcedit, благо, тестовые зарисовки в несколько строк. Вроде, mcedit без BOM сохраняет. Или я туплю? JoeUser Мне очень стыдно, но такую запись я не очень понимаю Как-то ни когда с потоками не работал и не особо их понимаю. Можно пример на С? Не С++, а чистом С? Цитата Кроме того, для работы непосредственно с кодировкой UTF-8 вариант существует. Для этого нужно работать исключительно со строками (вместо отдельных символов). Поскольку двухбайтовый символ в char не поместится, а в стороку - никаких проблем. Значит при распарсивании/модификации можно воспользоваться исключительно операциями со строками и всё получится. Насколько это дешевле и удобнее чем преобразования UTF-8 <-> UTF-16 не знаю, не пробовал. Вот и попробуй. Двухбайтовый символ помещается в short. А работать не с массивом, а со строкой... Сложнее) https://yandex.ru/search/?text=utf-8%20%D0%BF%D1%80%D0%B8%D0%B4%D1%83%D0%BC%D0%B0%D0%BB%D0%B8%20%D0%B8%D0%B7%D0%B2%D1%80%D0%B0%D1%89%D0%B5%D0%BD%D1%86%D1%8B&lr=213 Вот как эту строку перевести в нормальную и разпарсить по словам. Господа, огромное вам спасибо за советы и ссылки. Просто я что-то тыркаюсь башкой в стены и ни как не могу найти дверь. Я знаю С++, просто некоторые конструкции я ни когда не использовал. Вот и потоки прошли мимо. Мне куда удобнее printf выводить или принимать через scanf. Некоторые привычки пришли еще из Ассемблера и они черезвычайно сильны, да и менять их не хочется. |
Сообщ.
#15
,
|
|
|
Цитата HighMan @ Можно пример на С? Не С++, а чистом С? Низя. Я пользовался ништяками из STL, а это Цэ++. Если хочешь чистое Цэ - обрати внимание на это, пропробуй. |
Сообщ.
#16
,
|
|
|
Цитата HighMan @ Вот как эту строку перевести в нормальную и разпарсить по словам? Также, как и все остальные. Слова разделяются некоторыми символами, например пробелами. обозначим символ пробела как строку: const char* pSpace = " "; Будем искать смешения таких строк в исходной строке и копировать слова в контейнер. Например. |
Сообщ.
#17
,
|
|
|
Кто-нить может мне объяснить, что хочет ТС? Пример кода как конвертировать cp1251 в utf8 или что?
|
Сообщ.
#18
,
|
|
|
Цитата Кто-нить может мне объяснить, что хочет ТС? Пример кода как конвертировать cp1251 в utf8 или что? ТС хочет работать с utf8 как cp1251 ))) Добавлено Цитата JoeUser @ Низя. Я пользовался ништяками из STL, а это Цэ++. Если хочешь чистое Цэ - обрати внимание на это, пропробуй. Спасибо. Только с их ftp ни чего не качается. Долго-долго висит на попытке скачки и... кирдык. |
Сообщ.
#19
,
|
|
|
Цитата HighMan @ ТС хочет работать с utf8 как cp1251 ))) Что значит "как"? Что конкретно не получается? |
Сообщ.
#20
,
|
|
|
Цитата HighMan @ Мне куда удобнее printf выводить или принимать через scanf. Немножко чтения, немножко экспериментирования, я уверяю - ломка будет не сильно болезненна и не сильно долго ... По поводу 2-байтных кодировок и полноценного Юникода И тут могут ожидать детские грабли Два байта - это множество из 64к символов. Для сведения - школьный минимум японских школьников, завершивших среднее образование - 10к иероглифов. Газетных/общеупотребимых - 40к штук. На счет китайских не в курсе. Плюс еще некоторое множество). Даже при том, при всем, что японцы используют китайские иероглифы, как отдельные сущности, и как ключи для слово (вернее иероглифо-) образования. Добавим еще парочку алфавитов ... грузинский, арабский, тамильский, тайландский ... За 64к вылетаем со свистом!!! Так что, если Юникод ожидается "неполноценный" (допустим кириллица онли) - можно тупо написать в 50 строк свой парсер, это совсем не сложно. А если хотим адовой универсальности, пользуем что-то типа монстра ICU. Добавлено Цитата ЫукпШ @ Слова разделяются некоторыми символами, например пробелами. Не так) Если набранный текст однозначно отображается в win1251 (или в сp866, или в прочие однобайтовые кириллические) - все переводится табличными методами. Первая часть (латиница 0..127) переводится прямым отображением, остальные - отсеканием первого байта (если не ошибаюсь, смотреть лень, 0xe0) + опять по таблице второй байт. |
Сообщ.
#21
,
|
|
|
Цитата JoeUser @ Немножко чтения, немножко экспериментирования, я уверяю - ломка будет не сильно болезненна и не сильно долго ... По поводу 2-байтных кодировок и полноценного Юникода И тут могут ожидать детские грабли Два байта - это множество из 64к символов. Для сведения - школьный минимум японских школьников, завершивших среднее образование - 10к иероглифов. Газетных/общеупотребимых - 40к штук. На счет китайских не в курсе. Плюс еще некоторое множество). Даже при том, при всем, что японцы используют китайские иероглифы, как отдельные сущности, и как ключи для слово (вернее иероглифо-) образования. Добавим еще парочку алфавитов ... грузинский, арабский, тамильский, тайландский ... За 64к вылетаем со свистом!!! Так что, если Юникод ожидается "неполноценный" (допустим кириллица онли) - можно тупо написать в 50 строк свой парсер, это совсем не сложно. А если хотим адовой универсальности, пользуем что-то типа монстра ICU. Не хочется мне ломки. Даже короткой) Насчет 2х байтовых кодировок, это я привел для примера. Оно не годится, поскольку могут присутствовать и ироглифы и другие извращения. Если их исключать, то нет смысла, вообще, с UTF-8 связываться. cp1251 и ни какого геморроя. Похоже, очень ценную мысль из нашего общения я вывел: или подтягивать полноценного монстра, вроде ICU, или урезать осетра. Нужно серьезно осмысливать, какова необходимость в ироглифах и прочей арабской вязи. |
Сообщ.
#22
,
|
|
|
Цитата HighMan @ Спасибо. Только с их ftp ни чего не качается. Долго-долго висит на попытке скачки и... кирдык. Бедолага Лови - перекачал тебе их ща3тье сюда. Добавлено Цитата HighMan @ cp1251 и ни какого геморроя Там нет полного набора всех символов. Добавлено Цитата HighMan @ Нужно серьезно осмысливать, какова необходимость в ироглифах и прочей арабской вязи. Вот это тема!!! Тут уже с месяц-два назад по этому вопросу копья ломали И, уверяю, далеко не первый раз. А сводится все к простому и банальному "а хрен знает что мне нужно" Мораль басни такова - определись сперва с "техническими условиями" Добавлено Цитата HighMan @ подтягивать полноценного монстра Для справки - его дат-файл весит 25 метров. Я отказался уже года как три от этого жиробаса, да простит меня Далай Лама! |
Сообщ.
#23
,
|
|
|
Цитата Там нет полного набора всех символов. В ср1251 есть кириллица и есть латиница. А прочие немцы с франзузерами могут и латиницей перебиться. Тут важно мне самому понять: есть смысл во всех прочих кодировках, или и этого достаточно. Разумеется, определить это могу лишь я сам. А вообще... Может не стоит полноценно связываьбся с utf-8. Мне ведь не нужно будет всерьез работать со строками. Самая большая сложность, как перевести и распарсить url. Теоретичски, даже с этим можно особо не замарачиваться. Ну не через curl мне будет отсылаться запрос, а другим способом. Можно быстро нарисовать РНР код, который просто через socket будет мне отсылать запрос. |
Сообщ.
#24
,
|
|
|
Цитата HighMan @ А прочие немцы с франзузерами могут и латиницей перебиться. Это не так! Est-ce que, HighMan, vous étudiez le français avec plaisir? Если лишить французов выделенных символов, они взорвут Бастилию! Добавлено Цитата HighMan @ Может не стоит полноценно связываьбся с utf-8. Есть предложение - выбираем набор языков, которые хотим поддерживать. Храним в UTF-8. Работаем в фиксированном мультибайте - если попадаем в 2-байтовое пространство, то с ним, иначе в 4-х байтовое. Можно и второй вариант по-умолчанию. Возможно и нужно ... Если бы не адовая обработка текстовых данных (1-2-8 Гигов на современном этапе развития, ну и возможностей платформы). Диавол - в мелочахЪ |