Frage

Ich war ein CLI-Tool für Mac OS X (10.5 und höher) zu schreiben, die mit Befehlszeilenargumenten zu tun hat, die sehr wahrscheinlich Nicht-ASCII-Zeichen enthalten.

Für die weitere Verarbeitung konvertiere ich diese Argumente mit + [NSString stringWithCString: Codieren:].

Mein Problem ist, dass ich nicht gut Informationen finden konnte, wie der Charakter kodierenden zu bestimmen, von der Shell verwendet, bei dem der cli-Werkzeug aktiv ist.
Was kam ich mit als Lösung auf die folgenden:

NSDictionary *environment = [[NSProcessInfo processInfo] environment];
NSString *ianaName = [[environment objectForKey:@"LANG"] pathExtension];
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(
  CFStringConvertIANACharSetNameToEncoding( (CFStringRef)ianaName ) );

NSString *someArgument = [NSString stringWithCString:argv[someIndex] encoding:encoding];

Ich finde, dass ein wenig roh, aber - was ich denken läßt, dass ich verpasst etwas offensichtlich ... aber etwas

Sie haben einen gesünderen / Reiniger Weg im wesentlichen die gleiche erreichen?

Vielen Dank im Voraus

D

War es hilfreich?

Lösung 3

Okay, es stellt sich heraus, da keine zu sein scheint!

Wie Yuji wies darauf hin, die zugrunde liegende Codierung von Dateinamen ist UTF-8, egal was passiert. Daher benötigt man Griff zwei Szenarien :

  1. Argumente, die in typisiert sind, Zeichen für Zeichen durch den Benutzer.
  2. Argumente, die Tabula abgeschlossen sind oder die Ausgabe von Befehlen wie ls, da sie konvertieren keine Zeichen.

Der zweite Fall einfach durch die Annahme von UTF-8 abgedeckt ist.

Der erste Fall ist jedoch problematisch:

  • Unter Mac OS 10.6, $ LANG enthält die IANA-Namen der verwendeten Codierung wie de_DE.IANA_NAME.
  • Vor Snow Leopard, ist dies nicht der Fall für charsets andere als UTF-8!

Ich habe nicht jeden Test und jede charset könnte ich mir vorstellen, aber keiner der europäischen, wurden eingeschlossen. Stattdessen war $ LANG nur die Sprache-locale (de_DE in meinem Fall)!

Da die Ergebnisse des Aufrufs +[NSString stringWithCString:encoding:] mit einer falschen Codierung undefinierte , kann man nicht davon ausgehen, dass es nil in diesem Fall * zurück ( wenn z. B. seine ASCII-nur, es könnte perfekt funktionieren!).

Was zum Gesamt Chaos fügt hinzu, dass $LANG ist nicht Guarateed um zu sein, jedenfalls: Es gibt eine Checkbox in Terminal.app-Einstellungen, die es einem Benutzer nicht Set $LANG überhaupt ermöglicht (nicht zu sprechen von X11.app die jeden nicht-ASCII-Eingang zu handhaben scheint nicht ...).

So was übrig bleibt:

  1. Überprüfen auf das Vorhandensein von $LANG. Wenn es nicht gesetzt ist, Goto: 4
  2. Überprüfen Sie, ob $LANG Informationen über die Codierung enthält. Wenn dies nicht der Fall, Goto: 4
  3. !
  4. Überprüfen Sie, ob die Codierung Sie finden es UTF-8 ist. Wenn es Goto: 6, sonst ...
  5. Wenn argc größer als 2 und [[NSString stringWithCString: argv[0] encoding: NSUTF8StringEncoding] isEqualToString: yourForceUTFArgumentFlag] ist, drucken Sie, dass Sie zwingen die UTF-8 jetzt und Springen 6. Falls nicht:
  6. Angenommen, Sie wissen nichts, eine Warnung, dass Ihre Benutzer die Terminal-Codierung auf UTF-8 gesetzt sollte und betrachten kann yourForceUTFArgumentFlag als erstes Argument übergeben und exit () .
  7. Nehmen wir UTF-8 und tun, was Sie müssen ...

Sounds beschissen? Das ist, weil es ist, aber ich kann es nicht glauben, von jede saner Art und Weise zu tun.


Eine weitere Notiz aber: Wenn Sie mit UTF-8 als Kodierung, stringWithCString: Codieren:. NIL zurück, wenn es trifft nicht-ASCII-Zeichen in einem C-String, ist nicht codiert in UTF-8)

Andere Tipps

Die Antwort hängt davon ab, was der nicht-asciiness herkommt.

  1. In OS X, die Umgebungsvariable LANG hat nicht spiegeln die Wahl der Sprache in der GUI. Nur sehr wenige Menschen werden LANG auf der Kommandozeile gesetzt.
  2. Die Wahl des „System-Codierung“ auf der GUI in ~/.CFUserTextEncoding gespeichert ist, und kann durch CFStringGetSystemEncoding erhalten werden, finden Sie in diesem Apple-doc .
  3. sagte, dass diese "System-Codierung" ist selten verwendet außer in einer sehr alten, nicht-Unicode bewusst Software. Jeder vernünftige Cocoa-Programm verwendet nur Unicode und nichts anderes.
  4. Insbesondere der Dateipfad auf der Ebene der Cocoa wird immer in (eine Variante) UTF-8 codiert. Also, eine NSString von einem C-String zu erhalten, verwenden Sie

     NSString*string=[NSString stirngWithCString:cString encoding:NSUTF8Encoding];
    

    und einen C-String für den Dateipfad bekommen von einem NSString, Verwendung

     char*path=[string fileSystemRepresentation];
    

    Hier ist es empfehlenswert, nicht nur [string UTF8String] zu verwenden, aufgrund der Feinheit finden Sie in diesem Apple-doc .

  5. Also, ich empfehle Ihnen nicht um die Codierung zu kümmern und nur UTF-8 übernehmen.

  6. sagte, könnte es eine sehr kleine Anzahl von Menschen, die LANG auf der Kommandozeile setzt, und man könnte sie kümmern nehmen. Dann, was Sie getan haben, ist das einzige, was ich mit oben kommen kann.

Können Sie sich nicht [[NSProcessInfo processInfo] arguments] verwenden?

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