2010-11-11 31 views
6

En aras de aprendizaje de C y la comprensión de la diferencia entre archivos binarios y archivos de texto, Estoy intentando escribir una cadena de presentar ya que ambos tipos de archivos, así:¿Por qué fwrite() no escribe un archivo binario usando "wb", en C, en Mac OS X?

char * string = "I am a string!"; 

FILE * filePtrA = fopen("/output.txt", "wt"); 
fwrite(string, strlen(string), 1, filePtrA); 

FILE * filePtrB = fopen("/output.bin", "wb"); 
fwrite(string, strlen(string), 1, filePtrB); 

fclose(filePtrA); 
fclose(filePtrB); 

Sin embargo, tanto "wt""wb" y están escribiendo como un archivo de texto, donde "wb" debería estar escribiendo como un archivo binario. Hex aparece así para ambos archivos:

49 20 61 6D 20 61 20 73 74 72 69 6E 67 21 

¿Por qué ocurre esto y cómo puedo escribir algo como un archivo binario?

He leído que el sistema operativo (Mac OS X 10.6 - GCC 4.2) puede no diferenciar entre archivos binarios y de texto, aunque todavía estoy perplejo por qué un editor hexadecimal no detectaría ninguna diferencia.

+0

Me pregunto qué se espera de usted en el archivo "binario"? – Vovanium

Respuesta

6

Todos los archivos son binarios.

La diferencia entre "archivos de texto" y "archivos binarios" en el contexto de fopen es que la biblioteca estándar puede usar un filtro para leer y escribir el archivo en modo texto. En modo binario, lo que escribe siempre es lo que está escrito. El único ejemplo práctico que conozco es en Windows, donde abrir un archivo en modo texto lo convertirá entre terminaciones de línea estilo Windows (CRLF, "\r\n") y terminaciones de línea estilo C/estilo Unix (FL) , "\n"). Por ejemplo, cuando abre un archivo para leer en Windows en modo texto, las terminaciones de línea aparecerán como "\n" en su programa. Si tuviera que abrirlo en modo binario, las terminaciones de línea aparecerían como "\r\n" en su programa.


También puede inspeccionar su archivo con cat, por ejemplo:

gato nombre

Debe obtener la salida: I am a string!

+0

La sintaxis correcta es "nombre de archivo de gato". – Darron

+1

Para aclarar; Los corchetes angulares alrededor de "' filename' "solo tenían el propósito de ilustrar que es una variable, no algo para copiar palabra por palabra. Reemplace la cadena '' por el nombre de archivo real, y debería estar bien :) –

+4

Las versiones de Mac OS anteriores a OS X usaban '\ r' para designar terminaciones de línea, por lo que la distinción modo texto/modo binario era relevante allí también. – caf

1

El único modo texto de diferencia llega a las terminaciones de línea. Por lo tanto, si fprintf a \n se traducirá según la plataforma. Para su ejemplo, el modo binario o de texto no hace diferencia en lo que se escribe en el archivo.

3

Ambos archivos son archivos binarios. Son una copia exacta de los datos que envió al fwrite. Algunos sistemas operativos rotos tienen archivos de texto que no son binarios; tienen basura adicional como \r\n reemplazando \n, o registros de línea de tamaño fijo, etc. POSIX prohíbe todo esto. En cualquier sistema operativo POSIX, el texto y el modo binario son idénticos. Por supuesto, "wt" no es un argumento de modo válido para fopen. El modo de texto es predeterminado. El modificador t para solicitar el modo de texto es una extensión de implementaciones de Windows rotas donde el binario es el predeterminado pero el modo de texto está disponible por solicitud.

+0

¿Qué implementaciones tienen modo binario como modo predeterminado? Mi experiencia siempre ha sido que el modo texto es el predeterminado (y, en MS C, el modificador 't' es redundante pero la gente lo usa para mayor claridad) –

+0

@ M.M: El modo de texto es siempre el modo predeterminado; esto es requerido por ISO C. POSIX requiere que el modo de texto y el modo binario sean idénticos, de modo que no importa. –

1

En la mayoría Unix como sistemas, hay no diferencia entre abrir un archivo en modo texto vs. binario.Además, los datos que está escribiendo arriba no mostrarían ninguna diferencia, incluso en muchos sistemas que hacen tratan los archivos "text" y "binary" de manera diferente.

Por ejemplo, en Windows, la apertura de un archivo en modo texto normalmente significa que una "\ n" que escriba se traducirá a "\ r \ n" en el archivo real (y durante la lectura se realiza el opuesto) . Como no ha escrito una "\ n", esa traducción no sucederá.

+0

Reemplazar "más" con "todo". POSIX requiere que el modo de texto y el modo binario sean idénticos. Esto es tan fundamental que no creo que pueda considerar ningún sistema operativo que no sea "similar a Unix". –

1

Tienes razón. Esto no importa en los sistemas tipo Unix. Discussion from the cygwin camp. ¿Qué diferencia esperabas ver? Está escribiendo texto ASCII en un archivo, no datos binarios arbitrarios.

0

Unix como OS trata a ambos de la misma manera. No estoy seguro de que esta sea la respuesta correcta, pero si quiere poner un texto como hexadecimal en un archivo, intente aplicar \ x antes del texto.e.g. si intenta escribir un hola en un archivo, su memoria intermedia será:
char * buf = "hello";
Si desea escribir hexadecimal de "hello" en el archivo, su búfer debe ser así
char * buff = "\ x68 \ x65 \ x6c \ x6c \ x6f";
Espero que haya ayudado

+0

En la memoria, ambos 'buff' son exactamente iguales. No hay diferencia. – Zulan

+0

Sí, pero la diferencia es cuando lo escribe en el archivo. En el primer caso "hola", se escribirá como texto en el archivo, mientras que "\ x68 \ x65 \ x6c \ x6c \ x6f" se escribirá como hexadecimal en el archivo, no en el texto – fluffybunny

+0

Eso es incorrecto. Como no hay diferencia en la memoria, 'fwrite' solo escribe un bloque idéntico de datos en un archivo. Debe usar '\ x' solo para los caracteres que no pueden codificarse directamente en el archivo fuente. Solo inténtalo. – Zulan

Cuestiones relacionadas