metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2012-01-22 10:36 pm

atof, strtod и локаль.

Внезапно: а вот как положено в коде на С конвертить строку в double, если мы точно знаем, что в строке десятичный разделитель ".", и точно знаем, что код будут запускать на системе с адовыми локалями, у которых разделитель "," типа русской, белорусской итд? В дотнете, как положено, есть функция с параметром для локали и инвариантная локаль InvariantCulture. А в олдскульно-кошерном C как? setlocale(LC_NUMERIC,"C"); чо-то не рекомендуют, говорят, не thread-safe.

[identity profile] nicka-startcev.livejournal.com 2012-01-22 07:39 pm (UTC)(link)
не тред-сэйф -- значит вызвать один раз глобально, до того, как наплодить кучку тредов!

[identity profile] metaclass.livejournal.com 2012-01-22 07:41 pm (UTC)(link)
Ок. Если будет работа с гуем - юзера увидят разделитель не в своей локали (им в 99% похер, но мало ли).

[identity profile] justy-tylor.livejournal.com 2012-01-22 07:45 pm (UTC)(link)
Вставить в проект кусочек public domain кода, который делает это независимо от рантайма.

(Anonymous) 2012-01-22 07:46 pm (UTC)(link)
судя по всему никак, без своих или сторонних велосипедов(типа glib и т.д.)

--
xaep

[identity profile] nicka-startcev.livejournal.com 2012-01-22 07:50 pm (UTC)(link)
или руками предформатировать строку перед atof/strtod

[identity profile] metaclass.livejournal.com 2012-01-22 08:06 pm (UTC)(link)
А потом у меня юниоры спрашивают "а чего это у тебя половина стандартной либы в свою собственную библиотеку вынесена" :)

[identity profile] gds.livejournal.com 2012-01-22 08:09 pm (UTC)(link)
рекомендуется комментарий (к сигнатуре функции, если приемлемо), описывающий, чем эта функция отличается от стандартной. Все вопросы сведутся к тыканью носом в комментарий.

[identity profile] qehgt.livejournal.com 2012-01-22 08:12 pm (UTC)(link)
А комментарии надо сверху писать, почему этот код был написан.

[identity profile] dair-spb.livejournal.com 2012-01-22 08:13 pm (UTC)(link)
Чото у меня даже с локалью ru_RU.UTF-8 strtod воспринимает точку, но не запятую.

[identity profile] metaclass.livejournal.com 2012-01-22 08:21 pm (UTC)(link)
LC_NUMERIC="ru_RU.... ?

[identity profile] dair-spb.livejournal.com 2012-01-22 08:22 pm (UTC)(link)
LC_NUMERIC="ru_RU.UTF-8"

готов проверить с любым другим значением

[identity profile] metaclass.livejournal.com 2012-01-22 08:28 pm (UTC)(link)
 d = strtod("1.2",&t);
 printf("%f\n",d);

 setlocale(LC_NUMERIC,"ru_RU.UTF8");
 d = strtod("1,2",&t);
 printf("%f\n",d);


все работает, как положено, выдает 1.2 и 1,2

(Anonymous) 2012-01-22 08:31 pm (UTC)(link)
а setlocale(LC_ALL, "") сначала дёргали? а то оно без лишних телодвижений локаль из переменных окружения не ухватит.

--
xaep

[identity profile] dair-spb.livejournal.com 2012-01-22 08:36 pm (UTC)(link)
а, да, анонимный комментатор прав.

если специально вызвать setlocale, то всё "ломается".

Блин.

[identity profile] justy-tylor.livejournal.com 2012-01-22 08:36 pm (UTC)(link)
У меня не спрашивали. Когда системный код идёт в прошивку мобильника/телевизора или игру планируется портировать на консоли, то хрен предугадаешь, _что_ там окажется на месте стандартной либы. =)

[identity profile] madeveloper.livejournal.com 2012-01-22 09:14 pm (UTC)(link)
Плюсы не катят? Там можно stringstream со своей locale.

[identity profile] metaclass.livejournal.com 2012-01-22 09:23 pm (UTC)(link)
Счас придет айсед и накажет за упоминание плюсов :)

[identity profile] tzirechnoy.livejournal.com 2012-01-22 09:35 pm (UTC)(link)
1) Вы используете трэды? Тогда мы летим к вам (злобные баги).
2) Мнение, что разделителем можэт быть запятая -- это ересь, посему setlocale(LC_NUMERIC, "C")
3) char *dot;
if ((dot = strchr(s, '.'))) {
*dot = *nl_langinfo(RADIXCHAR);
}

[identity profile] fas-tm.livejournal.com 2012-01-22 09:39 pm (UTC)(link)
А как без них писать GUI нормальное ? А долгоиграющие бэкграунд воркеры ?
Расскажите.

[identity profile] max630.livejournal.com 2012-01-22 10:28 pm (UTC)(link)
*scanf игнорирует локаль, afaik

[identity profile] max630.livejournal.com 2012-01-22 10:36 pm (UTC)(link)
хм, не игнорирует.

[identity profile] max630.livejournal.com 2012-01-22 10:41 pm (UTC)(link)
Я думаю число тех кому не похер примерно равно числу тех кто охуеет от того что точка не принимается. Так что лучше похер.

Вообще для числа в гуе должен быть свой контрол, который в любой локали принимает и точку и запятую как разделители, и только показывают в зависимости от локали. То есть это задача не для функции парсенья.

[identity profile] freetiger.livejournal.com 2012-01-22 11:25 pm (UTC)(link)
положено-не знаю, я я бы делал компонент gui-платформа-предобертка как принцип

[identity profile] freetiger.livejournal.com 2012-01-23 12:39 am (UTC)(link)
положено-не знаю, я я бы делал компонент gui-платформа-предобертка как принцип

[identity profile] antontsau.livejournal.com 2012-01-23 02:40 am (UTC)(link)
настоящие юзеры в советских бухгалтериях пишут И точку И запятую. Типа 100.000,500 (ну или наоборот). Я на это нарвался еще в 86 году. Кто-то в какой-то замкадской дыре заполнил бумажный статопросник именно так, другой юзер ни на секунду не усомнясь ввел это в ЕСину, а у меня в статистике получились два и две трети библиотекаря.

Page 1 of 3