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

oll*_*llo 14 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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

0.83    -->     A5_c
Run Code Online (Sandbox Code Playgroud)

(给定字符串是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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

0       -->     A5_c
Run Code Online (Sandbox Code Playgroud)

(给定字符串仍然是5x char-array,但结果是错误的)


虽然0.83失败,但使用0,83(我的语言环境格式)可以正常使用Qt - 但没有Qt(默认行为)就失败了.如图所示 typeid(),没有QString使用 - 只有普通的旧C(++)字符数组.顺便说一下,同样的事情发生了std::string.

除此之外,使用a std::stringstream保持正常工作:

std::stringstream ss;
ss << "0.83"; // But the value into the stream
ss >> f;      // Get a float out of it
Run Code Online (Sandbox Code Playgroud)

结果:

0.83
Run Code Online (Sandbox Code Playgroud)

这里有一个问题:为什么char数组字符串和sscanf()调用受Qt影响?我理解为什么QString是本地化的,但破坏sscanf()(以及可能的其他stdio.h功能)对我来说听起来很邪恶.

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

use*_*710 9

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

这是正确的sscanf,在您的情况下,Qt会覆盖C locale使用默认C/C++配置时通常会获得的默认值.

你应该使用

setlocale(LC_NUMERIC,"C")

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

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

把事情重新设定为你所期望的.