2009-12-02 15 views
8

Tengo un código que manipula archivos binarios usando fstream con el indicador binario establecido y utilizando las funciones de E/S sin formato de lectura y escritura. Esto funciona correctamente en todos los sistemas que he usado (los bits en el archivo son exactamente como se esperaba), pero esos son básicamente todos inglés de los Estados Unidos. Me he estado preguntando sobre la posibilidad de que estos bytes sean modificados por un codecvt en un sistema diferente.Escribir archivos binarios usando C++: ¿importa la configuración regional predeterminada?

Parece que el estándar dice que usar E/S sin formato se comporta de la misma manera que poner caracteres en el streambuf usando sputc/sgetc. Esto conducirá a que se llamen las funciones de desbordamiento o desbordamiento en el streambuf, y parece que conducen a cosas que pasan por algún codecvt (por ejemplo, ver 27.8.1.4.3 en el estándar de C++). Para basic_filebuf, la creación de este codecvt se especifica en 27.8.1.1.5. Esto hace que parezca que los resultados dependerán de lo que devuelve basic_filebuf.getloc().

Entonces, mi pregunta es, ¿puedo asumir que una matriz de caracteres escrita usando stream.write en un sistema puede recuperarse textualmente usando ifstream.read en otro sistema, sin importar la configuración regional que cualquiera de las personas pueda estar usando en su ¿sistema? Me gustaría hacer las siguientes suposiciones:

  1. El programa está utilizando la configuración regional predeterminada (es decir, el programa no es cambiar el propio configuración regional en absoluto).
  2. Los sistemas tienen CHAR_BIT 8, tienen el mismo orden de bits dentro de cada byte, almacenan archivos como octetos, etc.
  3. Los objetos de flujo tienen establecido el indicador binario.
  4. No tenemos que preocuparnos por ninguna diferencia de endianess en esta etapa. Si algún byte en la matriz debe interpretarse como un valor de varios bytes, las conversiones de endianess se manejarán según sea necesario en una etapa posterior.

Si la configuración regional predeterminada no está garantizada para pasar este material sin modificaciones en alguna configuración del sistema (no sé, árabe o algo así), ¿cuál es la mejor forma de escribir archivos binarios usando C++?

+1

Creo que deberías agregar el mismo orden de bytes a tu suposición. ¿O estoy totalmente fuera de allí? –

+0

@TheScottMachine: Space_C0wb0y tiene razón, agregue el mismo orden de bytes a sus suposiciones – Stan

+0

Gracias, agregué una suposición adicional para aclarar. – TheScottMachine

Respuesta

0

En Windows debería estar bien, pero en otros sistemas operativos también debe verificar los finales de línea (solo como seguridad). La configuración regional predeterminada de C/C++ es "C", que es , no, según la configuración regional del sistema.

Esto no es una garantía. Como sabe, el compilador C/C++ y sus máquinas de destino varían mucho. Así que estás esperando que surjan problemas si mantienes todas esas suposiciones. Hay una sobrecarga insignificante para cambiar la configuración regional a menos que trate de hacerlo cientos de veces por segundo.

+0

Gracias, la información sobre la configuración regional predeterminada es lo que estaba buscando. Creo que las terminaciones de línea no deberían importar siempre que la bandera binaria se establezca en la secuencia. – TheScottMachine

1

Si tiene un indicador binario configurado, todo lo que escriba se escribirá en el archivo textualmente. Sin conversiones La forma de interpretar los bytes depende de usted (y posiblemente de la configuración regional).

Una cosa más: existe la posibilidad de roturas en diferentes lugares. Si, por ejemplo, su fuente de datos creó datos binarios basados ​​en la configuración regional (y el formato de estos datos cambiaría según la configuración regional, esta es una mala idea, por cierto). Esto causaría problemas al cargar datos en máquinas con diferente configuración regional. Esto es un error de diseño sin embargo.

Si solo usa tipos de datos estándar/estructuras que tengan el mismo formato/diseño, sin importar en qué configuración regional se crearon, todo debería estar bien.

1

Gracias por la ayuda. Solo pensé que podría ser útil publicar información adicional sobre esto que no encajaría en un comentario.

La configuración regional predeterminada para los programas en C++ es siempre la configuración regional "C" (http://www.cplusplus.com/reference/clibrary/clocale/setlocale/). Si esta es la única configuración regional utilizada en su programa, significa que el comportamiento no depende de la configuración regional particular de la máquina en la que se está ejecutando. También significa que la E/S no formateada para un char no sufre ninguna conversión de código (sin embargo, wchar_t podría ser una historia diferente). Esto significa que (dadas las suposiciones en la pregunta) leer y escribir debería permitir que los datos binarios sean recuperados sin modificaciones.

(a partir de la lectura de la documentación) Puede configurar globalmente la configuración regional de la aplicación para que coincida con la predeterminada del sistema llamando a setlocale (LC_ALL, ""), lo que significará que las transmisiones construidas desde ese punto utilizarán la configuración regional predeterminada del sistema. Para establecerlo de nuevo en la configuración regional "C", puede llamar a setlocale (LC_ALL, "C"), lo que significa que esto es lo que usarán las secuencias construidas en el futuro. También puede especificar que la "C" local se use para una transmisión que ya está construida llamando a stream.imbue (locale :: classic()).

Cuestiones relacionadas