为什么Qt会改变sscanf()的行为?

时间:2013-12-12 22:35:37

标签: c++ qt gcc qt4 scanf

我注意到,Qt(4.8)改变了sscanf()的行为。如果没有Qt sscanf()正常工作,但是,它只需要本地化的字符串。

这是一个最小化的例子:


没有Qt(普通C ++)

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 - 数组,结果正确)


使用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 - 数组,但结果错误)


虽然0.83失败,但使用0,83(我的语言环境格式)可以正常使用Qt - 但在没有Qt的情况下失败(默认行为)。如typeid()所示,没有使用QString - 只有普通的旧C(++)char数组。顺便说一下,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数组字符串和sscanf()调用受Qt影响?我理解为什么QString是本地化的,但打破sscanf()(以及可能还有其他stdio.h函数)对我来说听起来很邪恶。

背景:我将一个(非Qt)库(在代码深处某处包含sscanf())链接到Qt项目。结果:有些代码在这个项目中失败了,而它在其他地方都有效......(花了一些时间才找到原因......)

3 个答案:

答案 0 :(得分:7)

一般而言,如果您在标准库中获得了与流或I / O操作有关的功能,则可能会受到您的语言环境设置的影响。

这适用于sscanf,在您的情况下,Qt会覆盖您在使用默认C / C ++配置时通常会得到的默认C locale

你应该使用

setlocale(LC_NUMERIC,"C")

在初始化Qt环境之后,在这种情况下QApplication之后。

https://qt-project.org/doc/qt-5/qcoreapplication.html#locale-settings

将事情重新设定为您的期望。

答案 1 :(得分:2)

我怀疑QT会根据您的系统区域设置自动设置区域设置。实际上有standard localization library

设置C语言环境会更改列出on this page

的一系列函数的行为

但请注意,C ++流 not 会自动选择C语言环境,这就是std::stringstream正常运行的原因。

答案 2 :(得分:2)

Qt正在调用setlocale来设置C runtuime以使用您的语言环境。您可以尝试使用setlocale(LC_ALL,“C”)进行设置;但我不确定这会如何影响Qt的其余部分。