17

ファイルを引数として使用するアプリケーションの小さなラッパーを書いています。

ラッパーはUnicodeである必要があるため、使用している文字と文字列にはwchar_tを使用しています。今、私は問題に直面しています。プログラムの引数をwchar_tの配列とwchar_t文字列に含める必要があります。

出来ますか?main関数を次のように定義しています

int main(int argc, char *argv[])

wchar_tを使用する必要がありargvますか?

どうもありがとうございました。CでUnicodeを正しく使用する方法についての有用な情報が見つからないようです。

4

6 に答える 6

13

ポータブルコードはそれをサポートしていません。たとえば、Windowsは、wmainの代わりにを使用することをサポートしてmainいます。この場合、argvはワイド文字として渡されます。

于 2009-11-03T00:04:38.757 に答える
12

一般的に、いいえ。O / Sによって異なりますが、C標準では、「main()」の引数は「main(int argc、char ** argv)」または同等のものでなければならないとされているため、charとwchar_tが同じ基本型でない限り、あなたはそれを行うことはできません。

そうは言っても、UTF-8引数文字列をプログラムに取り込んで、それらをUTF-16またはUTF-32に変換してから、生活を続けることができます。

Mac(10.5.8、Leopard)では、次のようになりました。

Osiris JL: echo "ï€" | odx
0x0000: C3 AF E2 82 AC 0A                                 ......
0x0006:
Osiris JL: 

これがすべてUTF-8でエンコードされています。(odxは16進ダンププログラムです)。

参照:UNIX/Linux環境と対話するときにUTF-8エンコーディングが使用されるのはなぜですか

于 2009-11-03T00:05:10.970 に答える
9

Windowsでは、アプリがUnicode用にコンパイルされていない場合でも、GetCommandLineW()およびを使用しCommandLineToArgvW()てargvスタイルの配列を生成できます。wchar_t[]

于 2012-07-07T22:32:29.583 に答える
4

wmain()とにかくWindowsでは、UNICODEビルド用に持つことができます。しかし、ポータブルではありません。GCCまたはUnix/Linuxプラットフォームが同様のものを提供するかどうかはわかりません。

于 2009-11-03T00:03:48.747 に答える
3

Linux環境でUTF-8エンコーディングを使用していると仮定すると、次のコードは、C++でのUnicode処理を容易にするためにプログラムを準備します。

    int main(int argc, char * argv[]) {
      std::setlocale(LC_CTYPE, "");
      // ...
    }

次に、Linuxではwchar_t型は32ビットです。つまり、個々のUnicodeコードポイントを保持でき、C ++での従来の文字列処理(文字ごと)にwstring型を安全に使用できます。上記のsetlocale呼び出しでは、wcoutに挿入すると出力がUTF-8に自動的に変換され、wcinから抽出するとUTF-8入力がUTF-32に自動的に変換されます(1文字= 1コードポイント)。残っている唯一の問題は、argv[i]文字列がまだUTF-8でエンコードされていることです。

次の関数を使用して、UTF-8をUTF-32にデコードできます。入力文字列が破損している場合、UTF-8ルールが破られた場所まで、適切に変換された文字が返されます。より多くのエラー報告が必要な場合は、それを改善できます。しかし、argvデータの場合、それが正しいUTF-8であると安全に想定できます。

#define ARR_LEN(x) (sizeof(x)/sizeof(x[0]))

    wstring Convert(const char * s) {
        typedef unsigned char byte;
        struct Level { 
            byte Head, Data, Null; 
            Level(byte h, byte d) {
                Head = h; // the head shifted to the right
                Data = d; // number of data bits
                Null = h << d; // encoded byte with zero data bits
            }
            bool encoded(byte b) { return b>>Data == Head; }
        }; // struct Level
        Level lev[] = { 
            Level(2, 6),
            Level(6, 5), 
            Level(14, 4), 
            Level(30, 3), 
            Level(62, 2), 
            Level(126, 1)
        };

        wchar_t wc = 0;
        const char * p = s;
        wstring result;
        while (*p != 0) {
            byte b = *p++;
            if (b>>7 == 0) { // deal with ASCII
                wc = b;
                result.push_back(wc);
                continue;
            } // ASCII
            bool found = false;
            for (int i = 1; i < ARR_LEN(lev); ++i) {
                if (lev[i].encoded(b)) {
                    wc = b ^ lev[i].Null; // remove the head
                    wc <<= lev[0].Data * i;
                    for (int j = i; j > 0; --j) { // trailing bytes
                        if (*p == 0) return result; // unexpected
                        b = *p++;   
                        if (!lev[0].encoded(b)) // encoding corrupted
                            return result;
                        wchar_t tmp = b ^ lev[0].Null;
                        wc |= tmp << lev[0].Data*(j-1);
                    } // trailing bytes
                    result.push_back(wc);
                    found = true;
                    break;
                } // lev[i]
            }   // for lev
            if (!found) return result; // encoding incorrect
        }   // while
        return result;
    }   // wstring Convert
于 2012-07-07T11:50:59.137 に答える
2

Windowsでは、tchar.hと_tmainを使用できます。これらは、コンパイル時に_UNICODEシンボルが定義されている場合はwmainに、それ以外の場合はmainに変換されます。TCHAR * argv []は、Unicodeが定義されている場合は同様にWCHAR * argv []に展開され、定義されていない場合はchar *argv[]に展開されます。

メインメソッドをクロスプラットフォームで機能させたい場合は、同じ効果を持つ独自のマクロを定義できます。

TCHAR.hには、wcharとcharを変換するための便利なマクロがいくつか含まれています。

于 2009-11-03T00:47:19.200 に答える