簡體   English   中英

QChar :: isLetterOrNumber()失敗

[英]QChar::isLetterOrNumber() fails

我想將QStrings轉換為文件名。 由於我希望文件名看起來干凈,我想用下划線替換所有非字母和非數字。 以下代碼應該這樣做。

#include <iostream>
#include <QString>

QString makeFilename(const QString& title)
{
    QString result;
    for(QString::const_iterator itr = title.begin(); itr != title.end(); itr++)
     result.push_back(itr->isLetterOrNumber()?itr->toLower():'_');
    return result;
}

int main()
{
    QString str = "§";
    std::cout << makeFilename(str).toAscii().data() << std::endl;
}

但是,在我的計算機上,這不起作用,我得到一個輸出:

�_

尋找一個exporpation,調試告訴我QString("§").size() = 2> 1 = QString("a").size()

我的問題:

  • 為什么QString使用2個QChars作為“§”? (已解決
  • 你有makeFilename的解決方案嗎? 它對中國人也有用嗎?

好的,這是我的理論:當您將“§”文字提供給QString時,Qt使用一些默認編碼,因為您沒有設置一個。 如果你的編譯器使用UTF-8存儲字符串文字,你可能會給它2個字節,它被轉換成2個字符而不是1個字符。 同樣,你的“toAscii”輸出也很可能也是錯誤的。

從它的外觀來看,你必須找出你的編譯器用來存儲字符串文字的內容,並使用正確的值調用setCodecForCStrings

編輯:給出你的描述,如果我不知道編譯器的編碼,我可能首先嘗試QTextCodec :: codecForName(“UTF-8”)作為setCodec的參數:-)

除了其他人所說的,請記住, QString是UTF-16編碼的字符串。 在BMP之外的Unicode字符需要2個QChar值一起工作,稱為代理項對,以便對該字符進行編碼。 QString文檔盡可能多地說:

代碼值高於65535的Unicode字符使用代理對存儲,即兩個連續的QChars。

在循環訪問QString時,您沒有考慮到這一點。 您正在查看每個QChar而不檢查它是否屬於代理對。

試試這個:

QString makeFilename(const QString& title) 
{ 
    QString result; 

    QString::const_iterator itr = title.begin();
    QString::const_iterator end = title.end();

    while (itr != end)
    {
        if (!itr->isHighSurrogate())
        {
            if (itr->isLetterOrNumber())
            {
                result.push_back(itr->toLower()); 
                ++itr;
                continue;
            }
        }
        else
        {
            ++itr;
            if (itr == end)
                break; // error - missing low surrogate

            if (!itr->isLowSurrogate())
                break; // error - not a low surrogate

            /*
            letters/numbers should not need to be surrogated,
            but if you want to check for that then you can use
            QChar::surrogateToUcs4() and QChar::category() to
            check if the surrogate pair represents a Unicode
            letter/number codepoint...

            uint ch = QChar::surrogateToUcs4(*(itr-1), *itr);
            QChar::Category cat = QChar::category(ch);
            if (
                ((cat >= QChar::Number_DecimalDigit) && (cat <= QChar::Number_Other)) ||
                ((cat >= QChar::Letter_Uppercase) && (cat <= QChar::Letter_Other))
                )
            {
                result.push_back(QChar(ch).toLower()); 
                ++itr;
                continue;
            }
            */
        }

        result.push_back('_');
        ++itr; 
    }

    return result; 
} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM