ya hay algunas preguntas relacionadas con este problema. Creo que mi pregunta es un poco diferente porque no tengo un problema real, solo estoy pidiendo por interés académico. Sé que la implementación de Windows de UTF-16 a veces es contradictoria con el estándar Unicode (por ejemplo, intercalación) o más cercano al viejo UCS-2 que a UTF-16, pero mantendré la terminología "UTF-16" aquí por razones de sencillez.Cómo generar cadenas Unicode en la consola de Windows
Antecedentes: en Windows, todo es UTF-16. Independientemente de si está tratando con el kernel, el subsistema de gráficos, el sistema de archivos o lo que sea, está pasando cadenas UTF-16. No hay lugares o conjuntos de caracteres en el sentido de Unix. Para compatibilidad con las versiones medievales de Windows, hay una cosa llamada "páginas de códigos" que está obsoleta pero que sin embargo es compatible. AFAIK, solo hay una función correcta y no obsoleta para escribir cadenas en la consola, a saber, WriteConsoleW
, que toma una cadena UTF-16. Además, una discusión similar se aplica a las transmisiones de entrada, que también ignoraré.
Sin embargo, creo que esto representa un defecto de diseño en la API de Windows: hay una función genérica que se puede usar para escribir en todos los objetos de flujo (archivos, tuberías, consolas ...) llamados WriteFile
, pero esta función es byte- orientado y no acepta cadenas UTF-16. La documentación sugiere usar WriteConsoleW
para la salida de la consola, que está orientado al texto, y WriteFile
para todo lo demás, que está orientado a bytes. Dado que tanto las secuencias de consola como los objetos de archivo están representados por manejadores de objetos de kernel y las secuencias de consola pueden redirigirse, debe invocar una función para cada escritura en una secuencia de salida estándar que compruebe si el manejador representa una secuencia de consola o un archivo, rompiendo polymorphy. OTOH, creo que la separación de Windows entre cadenas de texto y bytes sin procesar (que se refleja en muchos otros sistemas como Java o Python) es conceptualmente superior al enfoque char*
de Unix que ignora las codificaciones y no distingue entre cadenas y matrices de bytes.
Así que mis preguntas son: ¿Qué hacer en esta situación? ¿Y por qué no se resuelve este problema incluso en las propias bibliotecas de Microsoft? Tanto .NET Framework como las bibliotecas C y C++ parecen adherirse al modelo de página de códigos obsoleto. ¿Cómo diseñaría la API de Windows o un marco de aplicación para eludir este problema?
Creo que el problema general (que no es fácil de resolver) es que todas las bibliotecas suponen que todas las secuencias están orientadas por bytes e implementan secuencias orientadas a texto además de eso. Sin embargo, vemos que Windows tiene secuencias especiales orientadas a texto en el nivel del sistema operativo, y las bibliotecas no pueden hacer frente a esto. Entonces, en cualquier caso, debemos introducir cambios significativos en todas las bibliotecas estándar. Una manera rápida y sucia sería tratar la consola como una secuencia orientada a bytes especial que acepta solo una codificación. Esto aún requiere que se eviten las bibliotecas estándar de C y C++ porque no implementan el modificador WriteFile
/WriteConsoleW
. ¿Es eso correcto?
sentimos, este "problema" suena como una entrada de blog en el encubrimiento ;-) – Philipp
esto podría estar relacionado con mi pregunta: http://superuser.com/questions/157225/even-on-windows-7- can-you-do-a-dir-and-be-able-to-see-filenames-that-has-unico –