Sane (r) manera de obtener de codificación de caracteres de la CLI en Mac OS X?
-
28-09-2019 - |
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
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
- Los argumentos que se escriben en, carácter a carácter, por parte del usuario.
- 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:
- Compruebe si hay presencia de
$LANG
. Si no se establece, Goto: 4 - Compruebe si
$LANG
contiene información sobre la codificación. Si no lo hace, Goto: 4 - Comprobar si la codificación observa que se produce UTF-8. Si se trata de Goto: 6, de lo contrario ...
- 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í: - 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 () . - 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.
- 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 establecerLANG
en la línea de comandos. - La elección del "sistema de codificación" en la interfaz gráfica de usuario se almacena en
~/.CFUserTextEncoding
, y se puede obtener porCFStringGetSystemEncoding
, ver este Apple doc . - 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.
-
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 usoNSString*string=[NSString stirngWithCString:cString encoding:NSUTF8Encoding];
y para obtener una C-secuencia de la ruta de archivo de una
NSString
, el usochar*path=[string fileSystemRepresentation];
A continuación, se recomienda no utilizar simplemente
[string UTF8String]
, debido a la sutileza, ver esto Apple doc . -
Por lo tanto, recomiendo que no se preocupan por la codificación y acaba de asumir UTF-8.
- 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]
?