Pregunta

estaba escribiendo un CLI-herramienta para Mac OS X (10.5 o superior) que tiene que lidiar con los argumentos de línea de comandos que son muy probable que contenga caracteres no ASCII.

Para un procesamiento adicional, convierto estos argumentos utilizando + [NSString stringWithCString: codificar:].

Mi problema es, que no podía encontrar buena información sobre cómo determinar la codificación de caracteres utilizado por el shell en el que dicho cli-herramienta se ejecuta en.
Lo que se me ocurrió como una solución es la siguiente:

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];

Me parece que un poco crudo, sin embargo - que me hace pensar que me perdí algo obvio ... pero lo

¿Hay una manera más sana / limpiador de lograr esencialmente el mismo?

Gracias de antemano

D

¿Fue útil?

Solución 3

Está bien, resulta que parece que hay ninguno!

Como Yuji señaló, la codificación subyacente de los nombres de archivo es UTF-8, no importa qué. Por lo tanto, uno necesita mango dos escenarios

  1. Los argumentos que se escriben en, carácter a carácter, por parte del usuario.
  2. Los argumentos que son tabuladores completado o la salida de comandos como ls, ya que no se convierten todos los caracteres.

El segundo caso es simplemente cubierto por la asunción de UTF-8.

El primer caso, sin embargo, es problemática:

  • En Mac OS 10.6, $ LANG contiene la IANA-nombre de la codificación utilizada como de_DE.IANA_NAME.
  • Antes de Snow Leopard, este no es el caso juegos de caracteres que no sean UTF-8!

no he probado todos y cada juego de caracteres que se le ocurría, pero se incluyó ninguna de las europeas. En su lugar, $ LANG solamente era el idioma de la configuración regional (de_DE en mi caso)!

Como los resultados de +[NSString stringWithCString:encoding:] llamar con una codificación incorrecta no están definidos , no se puede asumir con seguridad que le proporcione nil en ese caso * ( si, por ejemplo. que de ASCII-solamente, que podría funcionar perfectamente bien!).

Lo que añade a la confusión general es que $LANG no es guarateed para estar cerca, de todos modos: Hay una casilla de verificación en las preferencias de Terminal.app, que permite a un usuario no conjunto $LANG en absoluto (no hablan de X11.app que no parece para manejar cualquier entrada no ASCII ...).

Así que lo que queda:

  1. Compruebe si hay presencia de $LANG. Si no se establece, Goto: 4
  2. Compruebe si $LANG contiene información sobre la codificación. Si no lo hace, Goto: 4
  3. Comprobar si la codificación observa que se produce UTF-8. Si se trata de Goto: 6, de lo contrario ...
  4. Si argc es mayor que 2 y [[NSString stringWithCString: argv[0] encoding: NSUTF8StringEncoding] isEqualToString: yourForceUTFArgumentFlag], de impresión que está obligando a UTF-8 ahora y Goto 6. Si no es así:
  5. Supongamos que usted no sabe nada, emitir una advertencia de que el usuario debe establecer la codificación de la terminal a UTF-8 y puede considerar la aprobación de yourForceUTFArgumentFlag como primer argumento y Salir () .
  6. Supongamos UTF-8 y haga lo que tiene que ...

Sonidos de mierda? Esto se debe a que es, pero no puedo pensar en ninguna manera más sana de hacerlo.


Una nota más lejos sin embargo: Si está utilizando UTF-8 como codificación, stringWithCString: codificar:. Devuelve nil siempre que encuentre caracteres no ASCII en un C-String que es no codificado en UTF-8)

Otros consejos

La respuesta depende de lo que el no asciiness viene.

  1. En OS X, la variable de entorno LANG hace no reflejar la elección de la lengua en la GUI. Muy poca gente va a establecer LANG en la línea de comandos.
  2. La elección del "sistema de codificación" en la interfaz gráfica de usuario se almacena en ~/.CFUserTextEncoding, y se puede obtener por CFStringGetSystemEncoding, ver este Apple doc .
  3. Dicho esto, este "sistema de codificación" es rara vez se utiliza , excepto en unos muy viejos softwares conscientes, no Unicode. Cualquier programa de cuerdo cacao utiliza simplemente Unicode y nada más.
  4. En particular, la ruta de archivo en el nivel de cacao es siempre codificada en (una variante de) UTF-8. Por lo tanto, para obtener una NSString de una cadena C, el uso

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

    y para obtener una C-secuencia de la ruta de archivo de una NSString, el uso

     char*path=[string fileSystemRepresentation];
    

    A continuación, se recomienda no utilizar simplemente [string UTF8String], debido a la sutileza, ver esto Apple doc .

  5. Por lo tanto, recomiendo que no se preocupan por la codificación y acaba de asumir UTF-8.

  6. Dicho esto, no puede ser un número muy pequeño de personas que establece LANG en la línea de comandos, y es posible que desee hacerse cargo de ellos. Entonces, lo que hizo es la única cosa que puedo llegar a.

¿No puedes usar [[NSProcessInfo processInfo] arguments]?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top