Frage

Ich bin ein wenig Wrapper für eine Anwendung zu schreiben, die Dateien als Argumente verwendet.

Der Wrapper muss in Unicode sein, also verwende ich wchar_t für die Zeichen und Zeichenketten ich habe. Jetzt befinde ich mich in einem Problem, ich brauche die Argumente des Programms in einer Reihe von wchar_t ist und in einem wchar_t String haben.

Ist es möglich? Ich bin die Definition der main Funktion als

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

Sollte ich wchar_t 's für argv?

Vielen Dank, ich scheine nicht nützliche Informationen zu finden, wie Unicode zu verwenden, richtig in C.

War es hilfreich?

Lösung

In der Regel nicht. Es hängt von der O / S, aber der C-Standard sagt, dass die Argumente zu ‚main ()‘ sein muss ‚main (int argc, char ** argv)‘ oder gleichwertig, so es sei denn, char und wchar_t sind der gleiche Grundtyp Sie kann es nicht tun.

Having said that, könnten Sie UTF-8-Argument-Strings in das Programm, wandeln sie in UTF-16 oder UTF-32, und dann wieder mit Leben erhalten.

Auf einem Mac (10.5.8, Leopard), ich habe:

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

Das ist alles, UTF-8 codiert. (Odx ist ein Hex-Dump-Programm).

Siehe auch: Warum ist es, dass UTF-8-Codierung verwendet wird, wenn sie mit einer UNIX / Linux-Umgebung interagieren

Andere Tipps

Tragbare Code nicht unterstützt. Fenster (zum Beispiel) unterstützt mit wmain statt main, wobei in diesem Fall argv als breite Zeichen übergeben.

Unter Windows können Sie GetCommandLineW() und CommandLineToArgvW() verwenden, um einen argv-Stil wchar_t[] Array zu erzeugen, auch wenn die App nicht für Unicode kompiliert wird.

Unter Windows wie auch immer, können Sie eine wmain() haben für UNICODE baut. wenn auch nicht tragbar. Ich weiß nicht, ob GCC oder Unix / Linux-Plattformen ähnlich etwas bieten.

Unter der Annahme, dass Ihre Linux-Umgebung verwendet UTF-8-Codierung dann der folgende Code Ihr Programm für die einfache Unicode-Behandlung in C ++ wird vorbereitet:

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

Als nächstes Wchar_t Typ ist 32-Bit unter Linux, was bedeutet, es einzelne Unicode-Codepunkte aufnehmen kann, und Sie können sicher wstring Typen für klassische Stringverarbeitung in C ++ (Zeichen für Zeichen) verwenden. Mit setlocaleQ Anruf oben Gesagten Einsetzen in wcout automatisch die Ausgabe in UTF-8 übersetzen und aus WCIN Extrahieren automatisch UTF-8-Eingabe in UTF-32 (1 Zeichen = 1 code point) übersetzen. Das einzige Problem, das bleibt, ist, dass argv [i] Strings wird noch UTF-8 codiert.

Sie können die folgende Funktion verwenden UTF-8 in UTF-32 zu entschlüsseln. Wenn die Eingabezeichenfolge beschädigt ist, wird es zurückgeben ordnungsgemäß konvertierte Zeichen, bis der Ort, wo die UTF-8-Regeln gebrochen wurden. Man könnte es verbessern, wenn Sie mehr Fehlerberichterstattung benötigen. Aber für argv Daten kann man mit Sicherheit davon ausgehen, dass es richtig UTF-8 ist:

#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

Unter Windows können Sie tchar.h und _tmain verwenden, die in wmain gedreht werden, wenn das _UNICODE Symbol bei der Kompilierung definiert ist, oder Haupt anders. TCHAR * argv [] wird in ähnlicher Weise zu WCHAR erweitert werden * argv [], wenn Unicode definiert ist, und char * argv [], falls nicht.

Wenn Sie Ihre Haupt-Methode arbeiten Cross-Plattform haben wollen, können Sie Ihre eigenen Makros auf den gleichen Effekt definieren.

tchar.h enthält eine Reihe von Convenience-Makros zur Konvertierung zwischen wchar und Saibling.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top