簡體   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