Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.145.97.248] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#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, а это Цэ++. Если хочешь чистое Цэ - обрати внимание на это, пропробуй. |