Почему Qt изменяет поведение sscanf()?
Я заметил, что Qt (4.8) меняет поведение sscanf()
. Без Qt sscanf()
работает как обычно, но с помощью он принимает только локализованные строки.
Здесь приведен пример с минимальным значением:
Без Qt (простой С++)
int main(int argc, char *argv[])
{
float f;
sscanf("0.83", "%f", &f);
std::cout << f << "\t-->\t" << typeid("0.83").name() << std::endl;
return 0;
}
Вывод:
0.83 --> A5_c
(данная строка представляет собой 5x char
-array, результат правильный)
С Qt
int main(int argc, char *argv[])
{
/*
* This breaks sscanf() for the whole (!) project
* and linked libraries too!
*/
QApplication(argc, argv);
float f;
sscanf("0.83", "%f", &f);
std::cout << f << "\t-->\t" << typeid("0.83").name() << std::endl;
return 0;
}
Вывод:
0 --> A5_c
(задана строка 5x char
-array, но результат неверен)
В то время как 0.83
не работает, использование 0,83
(мой формат локали) отлично работает с Qt - но не работает без Qt (поведение по умолчанию). Как показано typeid()
, там не используется QString
- только старые старые C (++) char -arrays. Btw., То же самое происходит с std::string
.
Кроме того, использование std::stringstream
работает нормально:
std::stringstream ss;
ss << "0.83"; // But the value into the stream
ss >> f; // Get a float out of it
Результат:
0.83
И вот возникает вопрос: Почему char -array строки и sscanf()
вызовы, затронутые Qt? Я понимаю, почему QString
локализованы, но нарушение sscanf()
(и, возможно, других функций stdio.h
) звучит для меня злом.
Фон: я связал библиотеку (не Qt), содержащую sscanf()
где-то глубоко в коде, в проекте Qt. Результат: Некоторый код не удался в этом проекте, в то время как он работал везде... (потребовалось некоторое время, чтобы найти причину...)
Ответы
Ответ 1
В общих чертах, если вы получаете функцию в стандартной библиотеке, которая имеет какое-то отношение к потокам или операциям ввода-вывода, скорее всего, это повлияет на ваши настройки локали.
Это верно для sscanf
, и в вашем случае Qt переопределяет значение по умолчанию C locale
, которое вы обычно получаете при использовании конфигурации по умолчанию C/С++.
вы должны использовать
setlocale(LC_NUMERIC,"C")
сразу после инициализации вашей среды Qt, в этом случае после QApplication
.
https://qt-project.org/doc/qt-5/qcoreapplication.html#locale-settings
чтобы вернуть все, что вы ожидаете.
Ответ 2
Я подозреваю, что QT автоматически устанавливает локаль автоматически на основе вашей системы. Фактически существует стандартная библиотека локализации.
Настройка локали C изменяет поведение набора функций, перечисленных на этой странице.
Обратите внимание, однако, что потоки С++ не автоматически выбирают языковой стандарт C, поэтому ваш std::stringstream
ведет себя нормально.
Ответ 3
Qt вызывает setlocale, чтобы установить C runtuime для использования вашей локали. Вы можете попробовать установить его с помощью setlocale (LC_ALL, "C" ); но я не уверен, как это повлияет на остальную часть Qt.