LINUX.ORG.RU

Переносимый printf


0

1

Кто-нибудь пользовался переносимыми библиотеками/реализациями *printf - какими?
Смотрел пока тут:
http://www.and.org/vstr/printf_comparison
http://www.ijs.si/software/snprintf

Ищу что-то с поддержкой wchar и чтобы библиотека не навязывала свой строковый класс.

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

> а давно printf из стандартной библиотеки перестал быть переносимым ?
С тех пор как повился второй по счету компилятор =)

Если интересно, примеры:
vsnprintf [gcc], _vsnprintf [msvc] - разное поведение
vsnprintf [char], vswprintf [wchar] - разное возвращаемое значение
_vscprintf [mcvc only]
wprintf [gcc], wprintf [msvc] - разная интерпритация %s

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

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

Если интересно, примеры: [..]

сравнение не совсем корректное: ms'у законы не писаны, т.ч. там всё что хочеш может быть. char/wchar — разные типы, разные функции.

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

Пример проблемы?

wprintf(L"hello %s", "world");

Или

int bufsiz = vsnprintf(buff, size, fmt);
#ifdef GCC
if (bufsiz > size)
    buff = malloc(bufsiz);
#elsif MSVC
if (bufsiz == -1)
    buff = malloc(_vscprintf(fmt));
#endif

И т.п.

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

> сравнение не совсем корректное: ms'у законы не писаны
Поэтому самое правильное решение - использовать переносимую реализацию вместо их.

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

> от wchar'а геморроя больше чем пользы
Как и в других плохих вещах, в wchar возникает необходимость из-за винды.

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

Как раз из-за венды мысли о wchar'е должны были бы сразу пропасть, ибо размеры его в венде и в линухе разные. Я вообще еще ни разу не встречал ни одного серьезного коммерческого проекта в котором использовали бы wchar.

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

> cat test.c
#include <stdio.h>
#include <wchar.h>

int main()
{
wprintf(L"hello %s\n", «world»);
return 0;
}

gcc test.c -o test

./test


hello world


что, собственно, я сделал не так?

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

В 99.99% случаев проверять код возврата этих функций не нужно. Переаллокация памяти в случае если в буфер что-то не влезло выглядит страшно.

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

> что, собственно, я сделал не так?
Никто не винит ув. анонимуса в том, что в Visual C++ реализация такая: http://msdn.microsoft.com/en-us/library/hf4y5e3w%28v=vs.80%29.aspx

When used with printf functions, specifies a single-byte–character string; when used with wprintf functions, specifies a wide-character string.

Characters are printed up to the first null character or until the precision value is reached.

user_2190
() автор топика
Ответ на: комментарий от Reset
Я вообще еще ни разу не встречал ни одного серьезного коммерческого проекта в котором использовали бы wchar.

ядро WINDOWS NT ? полностью на wchar_t

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

не видел его сорцов, но в ms и не такие извраты случаются

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

> Я вообще еще ни разу не встречал ни одного серьезного коммерческого проекта в котором использовали бы wchar.

Разве в винде не определяют _UNICODE в 90% приложений? Вместо этого каждый раз перекодируют строки в UTF16 перед передачей в WinAPI?

Переаллокация памяти в случае если в буфер что-то не влезло выглядит страшно.

Ну, это, очевидно, зависит от конкретного случая.

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

Разве в винде не определяют _UNICODE в 90% приложений? Вместо этого каждый раз перекодируют строки в UTF16 перед передачей в WinAPI?

Если пишут кроссплатформенно, то такими извратами не страдают. Обычно используется char * с utf-8 и какая-нибудь кроссплатформенная обвязка, чтобы напрямую не работать с winapi.

Reset ★★★★★
()

(CL-USER:FORMAT)

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

Иногда этого хватает, но в случае, когда из-за этого постоянно приходится конвертировать строки, только чтобы хранить их в u8, а не u16, лучше просто хранить их в u16.
Если не определен _UNICODE, лего забыть конвертнуть строку перед вызовом winapi и получить багу.

Те же boost.filesystem и qt - примеры обвязок - используют wchar_t (первый - только в винде).

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

так как ядро WINDOWS NT юникодное и использует wchar_t то если в проекте не определен макрос UNICODE вызываются переходники с суффиксами A например #ifdef UNICODE #define SetWindowText SetWindowTextW #else #define SetWindowText SetWindowTextA #endif

это реально экспортируемые функции их задача очень проста сконвертить строки в wchar_t и вызвать W (SetWindowTextW) версии поэтому под вендой просто не выгодно юзать не wchar_t потому что тем самым мы напрягаем дополнительный код конвертить при каждом вызове строки в UNICODE

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

так как ядро WINDOWS NT юникодное и использует wchar_t то если в проекте не определен макрос UNICODE вызываются переходники с суффиксами A например

#ifdef UNICODE
#define SetWindowText SetWindowTextW
#else
#define SetWindowText SetWindowTextA
#endif
это реально экспортируемые функции их задача очень проста сконвертить строки в wchar_t и вызвать W (SetWindowTextW) версии поэтому под вендой просто не выгодно юзать не wchar_t потому что тем самым мы напрягаем дополнительный код конвертить при каждом вызове строки в UNICODE

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

Основное ограничение, что версии *A не поддерживают нормально utf8, только всякие cp1251.

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

Те же boost.filesystem и qt - примеры обвязок - используют wchar_t (первый - только в винде).

что они там используют внутри никого не волнует, главное, что наружу торчит человеческий интерфейс без всяких wchar_t

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

См. boost::filesystem::path::value_type
Но, да, при этом path умеетв конвертировать свои аргументы char -> wchar, так что я не прав

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

>Если пишут кроссплатформенно, то такими извратами не страдают. Обычно используется char * с utf-8 и какая-нибудь кроссплатформенная обвязка, чтобы напрямую не работать с winapi.

Все COM-овские строки по определению wide, например. Строки в jni и P/Invoke под виндой тоже wide.

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

Ну дык нету, да. (В винде wchar_t - 16 битный, в линуксе - 32 битный)

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