tipos programas lenguaje ejemplos dev datos comandos basico c++ c mac-classic

programas - manual de c++ basico



¿Cuál es el valor de ''/ n'' en compiladores C para Mac OS antiguo? (5)

Fondo:

En versiones de Mac OS hasta la versión 9, la representación estándar para archivos de texto usaba un carácter ASCII CR (retorno de carro), valor decimal 13, para marcar el final de una línea.

Mac OS 10, a diferencia de versiones anteriores, es de tipo UNIX y usa el carácter ASCII LF (avance de línea), valor decimal 10, para marcar el final de una línea.

La pregunta es, ¿cuáles son los valores de las constantes de los caracteres ''/n'' y ''/r'' en los compiladores de C y C ++ para las versiones de Mac OS anteriores a OS X?

Hay (al menos) dos enfoques posibles que podrían haberse tomado:

  1. Trate ''/n'' como el carácter ASCII LF y conviértalo a CR desde la salida y la entrada desde flujos de texto (similar a la conversión entre LF y CR-LF en sistemas Windows); o
  2. Trate ''/n'' como el carácter ASCII CR, que no requiere conversión en entrada o salida.

Habría algunos problemas potenciales con el segundo enfoque. Uno es que el código que asume ''/n'' es LF podría fallar. (Dicho código es intrínsecamente no portátil de todos modos.) El otro es que todavía debe haber un valor distinto para ''/r'' , y en un sistema basado en ASCII, CR es el único valor razonable. Y el estándar C no permite ''/n'' == ''/r'' (gracias a mafso para encontrar la cita, 5.2.2 párrafo 3), por lo que algún otro valor debería ser usado para ''/r'' .

¿Cuál es el resultado de este programa C cuando se compila y ejecuta bajo Mac OS N , para N menos de 10?

#include <stdio.h> int main(void) { printf("''//n'' = %d/n", ''/n''); printf("''//r'' = %d/n", ''/r''); if (''/n'' == ''/r'') { printf("Hmm, this could be a problem/n"); } }

La pregunta se aplica tanto a C como a C ++. Supongo que la respuesta sería la misma para ambos.

La respuesta también podría variar de un compilador de C a otro, pero espero que los implementadores del compilador hayan mantenido la coherencia entre ellos.

Para ser claro, no estoy preguntando qué representación solían presentar versiones anteriores de Mac OS para representar el final de línea en los archivos de texto . Mi pregunta es específica y solo sobre los valores de las constantes ''/n'' y ''/r'' en el código fuente C o C ++. Soy consciente de que al imprimir ''/n'' (cualquiera que sea su valor) en una secuencia de texto, se convierte en la representación de fin de línea del sistema (en este caso, ASCII CR); ese comportamiento es requerido por el estándar C.


En compiladores de Mac más antiguos, los roles de / y / n eran invertidos: Teníamos ''/ n'' == 13 y ''/ r'' == 10, mientras que hoy ''/ n'' == 10 y ''/ r'' == 13. Muy divertido durante la fase de transición. Escriba un ''/ n'' en un archivo con un compilador anterior, lea el archivo con un nuevo compilador y obtenga un ''/ r'' (por supuesto, las dos veces que tuvo el número 13).


Especificación del lenguaje C:

5.2.2
...
2 Las secuencias de escape alfabético que representan caracteres no gráficos en el juego de caracteres de ejecución están destinadas a producir acciones en los dispositivos de visualización de la siguiente manera:
...
/ n (nueva línea) Mueve la posición activa a la posición inicial de la siguiente línea.
/ r (retorno de carro) Mueve la posición activa a la posición inicial de la línea actual.

así /n representa el carácter apropiado en esa codificación de caracteres ... en ASCII es el carácter LF


Hice una búsqueda y encontré esta página con una discusión antigua donde se puede encontrar especialmente lo siguiente:

La implementación Metrowerks MacOS va un paso más allá al revertir la importancia de CR y LF con respecto a los escapes ''/ r'' y ''/ n'' en I / O que involucran un archivo, pero no en ningún otro contexto. Esto significa que si abre un ARCHIVO o una cadena en el modo de texto, cada ''/ r'' se emitirá allí como una LF y cada ''/ n'' se emitirá como CR, y lo mismo se aplicará a la entrada - el escape- to-ASCII-las correspondencias binarias están invertidas. Sin embargo, no se invierten en la memoria, por ejemplo, con sprintf () en un buffer o con std :: stringstream. Encuentro esto confuso y, si no no estándar, al menos peor que otras implementaciones.

Resulta que hay una solución con MSL: si abre el archivo en modo binario, ''/ n'' siempre == LF y ''/ r'' siempre == CR. Esto es lo que quería, pero al obtener esta información también obtuve mucha justificación por parte de la gente de que esta era la forma "estándar" de obtener lo que quería, cuando siento que esto es más como una solución para un error en su implementación. Después de todo, CR y LF son valores ASCII de 7 bits y espero poder utilizarlos de forma estándar con un archivo abierto en modo texto.

(Una respuesta deja en claro que esto no es una violación de la norma).

Así que obviamente hubo al menos una implementación que usó /n y /r con los valores ASCII usuales, pero los tradujo en un archivo (no binario) de salida (simplemente intercambiándolos).


Los valores de las constantes de caracteres /r y /n eran exactamente los mismos en los entornos de Mac OS Clásicos que en cualquier otro sitio: /r 0x0d era CR era ASCII 13 ( 0x0d ); /n era LF el ASCII 10 ( 0x0a ). Lo único que era diferente en Classic Mac OS era que se usaba como la línea "estándar" que termina en los editores de texto, al igual que /n se usa en sistemas UNIX, o /r/n en sistemas DOS y Windows.

Aquí hay una captura de pantalla de un programa de prueba simple que se ejecuta en Metrowerks CodeWarrior en Mac OS 9, por ejemplo:

Tenga en cuenta que los sistemas Classic Mac OS no tenían una biblioteca C estándar en todo el sistema. Las funciones como printf() solo estaban presentes como parte de bibliotecas específicas del compilador como SIOUX para CodeWarrior, que implementaba E / S estándar C escribiendo el resultado en una ventana con un campo de texto. Como tal, algunas implementaciones de E / S de archivos estándar pueden haber realizado alguna traducción automática entre /r /n , que puede ser lo que estás pensando. (Muchos sistemas Windows hacen cosas similares para /r/n si no pasas el indicador "b" a fopen() , por ejemplo.) Sin embargo, no había nada de eso en la Caja de herramientas de Mac OS.


No tengo un viejo compilador de Mac para comprobar si siguen esto, pero el valor numérico de ''/n'' debería ser el mismo que el carácter de línea nueva ASCII (dado que esos compiladores usaban codificación ASCII compatible como la codificación de ejecución, que Creo que lo hicieron). ''/r'' debe tener el mismo valor numérico que el retorno de carro ASCII.

La biblioteca o las funciones del sistema operativo que manejan los archivos del modo de escritura de texto es responsable de convertir el valor numérico de ''/n'' en lo que el sistema operativo use para terminar las líneas. Los valores numéricos de estos caracteres en tiempo de ejecución están determinados por completo por el conjunto de caracteres de ejecución.

Por lo tanto, dado que todavía somos codificaciones de ejecución compatibles con ASCII, los valores numéricos deben ser los mismos que con los compiladores clásicos de Mac.