繁体   English   中英

将 QString 转换为 const char*

[英]Convert a QString to a const char*

为了创建自定义异常类,我需要将QString转换为const char* 这是上述类的主要代码:

// File "Exception.cpp"

const auto MESSAGE_PREFIX = QStringLiteral("Exception ");

Exception::Exception(const char* file, int line, const QString& cause)
    : m_Message{MESSAGE_PREFIX + file + ':' + QString::number(line) + ": " + cause}
{
}

const char* Exception::what() const noexcept
{
    // QString -> const char*
    const auto ba = m_Message.toLocal8Bit();
    return ba.constData();
}

因此,转换发生在重写方法Exception::what ,并且返回的 C 字符串指示抛出异常的文件等。

另外,我定义了一个有助于抛出异常的宏THROW_EXCEPTION_IF()

// File "exception_macros.h"

#include "Exception.h"

#ifdef Q_OS_WINDOWS
#define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#else
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#endif

#define THROW_EXCEPTION_IF(condition, cause)
    if (condition) {
        auto str = QString{};
        QTextStream stream{&str};
        stream << cause;
        throw Exception{__FILENAME__, __LINE__, str};
    }

最后,我使用以下代码测试上述宏:

void TestException::testMacro()
{
    try {
        THROW_EXCEPTION_IF(true, "Test")
        QVERIFY(false);
   }
   catch (const std::exception& e) {
       QVERIFY(true);
       QCOMPARE(QString{e.what()}, QStringLiteral("Exception TestException.cpp:36: Test"));
   }
}

这就是问题所在:当我在 Linux(Qt 5.7.1、GCC 6.3)上运行此测试时,它失败并显示以下消息:

FAIL!: TestException::testMacro() 比较值不一样
实际 (QString{e.what()}):“异常 TestExn\\T\e\s\t\E\x\n\\\n\\\”预期的异常(Q3.测试")): "异常 TestException.cpp:36: 测试"

在 Windows (Qt 5.15) 和 MSVC 2019 上也是同样的问题,但它适用于 MinGW 8.1 此外,在Linux上,当我更换m_Message.toLocal8bit()m_Message.toLatin1()测试顺利通过。 我认为 Unicode 字符有问题,但我不明白我的代码哪里出了问题。 非常感谢您的帮助。

你的问题是你返回了一个无效的指针:

const auto ba = m_Message.toLocal8Bit(); // here you create a bytearray
return ba.constData();//here you take the pointer to the data of the bytearray
                      //then you destroy the array, hence the pointer.
                      //then you return an invalid pointer

您在不同平台上有不同的行为,因为当指针不再可用时无法保证。 这取决于平台、编译器、编译标志等。

为什么它不起作用

我同意 Pablo Yaggi 的观点,即您正在尝试访问被破坏的数据,请参阅QByteArray::constData

只要字节数组未被重新分配或销毁,[ const char * ] 指针就保持有效。

解决方案

您应该将QByteArray (由toLocal8Bit返回)存储在您的异常类(而不是QString )中。 请注意,您可能希望返回 UTF-8 编码的字符串(请参阅toUtf8 )以支持所有(特殊)字符。 如果遇到不受支持的字符,则toLocal8BittoLatin1的行为未定义:

如果此字符串包含无法在语言环境中编码的任何字符,则返回的字节数组未定义。 这些字符可能会被抑制或替换为另一个字符。 [来源]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM