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

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

[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] max630.livejournal.com 2012-01-22 10:28 pm (UTC)(link)
*scanf игнорирует локаль, afaik

[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 году. Кто-то в какой-то замкадской дыре заполнил бумажный статопросник именно так, другой юзер ни на секунду не усомнясь ввел это в ЕСину, а у меня в статистике получились два и две трети библиотекаря.

[identity profile] blackyblack.livejournal.com 2012-01-23 05:01 am (UTC)(link)
Я всю жизнь думал, что strtod только с точкой разделителем работает... Как выяснилось, локаль всё-таки влияет. Но вон ниже пишут, что влияет локаль только если явно задать, а по умолчанию, видимо, должна быть точка.
Соответственно, решение может быть такое:
а) не указывать локаль, а в си само не подхватится.
б) указать явно какую-нибудь адекватную в самом начале программы.

[identity profile] anatoly borodin (from livejournal.com) 2012-01-23 05:45 am (UTC)(link)
> setlocale(LC_NUMERIC,"C"); чо-то не рекомендуют, говорят, не thread-safe.


Синглтон, фигле.

[identity profile] vp.livejournal.com 2012-01-23 07:12 am (UTC)(link)
Откуда вообще в нашей стране в качестве разделителя взялась запятая? Бесед.