0

QStringをファイル名に変換したい。ファイル名をきれいに見せたいので、すべての非文字と非数字をアンダースコアに置き換えたいと思います。次のコードはそれを行う必要があります。

#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;
}

しかし、私のコンピューターでは、これは機能しません。出力として取得します。

�_

エクスペンションを探していると、デバッグによりQString("§").size()= 2>1=と表示されQString("a").size()ます。

私の質問:

  • QStringが「§」に2つのQCharを使用するのはなぜですか?(解決済み
  • 解決策はありmakeFilenameますか?それは中国人にも役立つでしょうか?
4

2 に答える 2

1

わかりました。これが私の理論です。「§」リテラルをQStringにフィードすると、デフォルトのエンコーディングが設定されていないため、Qtはデフォルトのエンコーディングを使用します。コンパイラがUTF-8を使用して文字列リテラルを格納している場合は、1バイトではなく2文字に変換される2バイトをフィードしている可能性があります。同様に、「toAscii」出力もおそらく間違ったことをします。

その外観から、コンパイラが文字列リテラルを格納するために何を使用しているかを調べ、正しい値でsetCodecForCStringsを呼び出す必要があります。

編集:あなたの説明を考えると、コンパイラのエンコーディングがわからない場合は、最初にsetCodecのパラメータとしてQTextCodec :: codecForName( "UTF-8")を試してみます:-)

于 2012-10-03T15:35:17.247 に答える
1

他の人が言ったことに加えて、aQStringはUTF-16でエンコードされた文字列であることに注意してください。BMPの外部にあるUnicode文字は、QCharその文字をエンコードするために、サロゲートペアと呼ばれる2つの値が一緒に機能する必要があります。QStringのドキュメントには次のように書かれています。

65535を超えるコード値を持つUnicode文字は、サロゲートペア、つまり2つの連続するQCharを使用して格納されます。

をループするときに、それを考慮していませんQStringQCharサロゲートペアに属しているかどうかを確認せずに、それぞれを個別に確認しています。

代わりにこれを試してください:

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; 
} 
于 2012-10-03T21:24:33.717 に答える