Pregunta

Quiero almacenar cadenas en un archivo binario, junto con una gran cantidad de otros datos, im utilizando el código de abajo (cuando lo uso para las propiedades serán malloc'd las cuerdas) Puedo escribir en el fichero. Ive miró en un editor hexadecimal. Im no estoy seguro de que escriben correctamente el terminador nulo (o si necesito). cuando leí de vuelta consigo la misma longitud de cadena que guardé, pero no la cadena. ¿Qué estoy haciendo mal?

FILE *fp = fopen("mybinfile.ttt", "wb");

char drumCString[6] = "Hello\0";
printf("%s\n", drumCString);    
//the string length + 1 for the null terminator
unsigned short sizeOfString = strlen(drumCString) + 1;
fwrite(&sizeOfString, sizeof(unsigned short), 1, fp);

//write the string
fwrite(drumCString, sizeof(char), sizeOfString, fp);

fclose(fp);

fp = fopen("mybinfile.ttt", "rb");  

unsigned short stringLength = 0;
fread(&stringLength, sizeof(unsigned short), 1, fp);

char *drumReadString = malloc(sizeof(char) * stringLength);
int count = fread(&drumReadString, sizeof(char), stringLength, fp);

//CRASH POINT
printf("%s\n", drumReadString);

fclose(fp); 
¿Fue útil?

Solución

Se está haciendo mal durante la lectura. de haber introducido la y para la variable puntero es por eso que da fallo de segmentación.

Quité que funciona bien y vuelve Hola correctamente.

int count = fread(drumReadString, sizeof(char), stringLength, fp);

Otros consejos

Veo un par de cuestiones, algunas problemática, algunos estilística.

  • Usted realmente debe probar los valores de retorno de malloc, fread y fwrite ya que es posible que la asignación puede fallar, y no hay datos puede ser leído o escrito.
  • sizeof(char) es siempre 1, no hay necesidad de multiplicar por ella.
  • El array de caracteres "Hello\0" es en realidad 7 bytes de longitud. No es necesario añadir un terminador nulo superflua.
  • Yo prefiero el char x[] = "xxx"; idioma en lugar de especificar una longitud definida (a menos que desee una serie más larga que la cadena, por supuesto).
  • Cuando fread(&drumReadString ..., en realidad estás sobrescribir el puntero , no la memoria que apunta. Esta es la causa de su accidente. Cabe fread(drumReadString ....

Un par de consejos:

1

A \0 de terminación está implícita en cualquier cadena de comillas dobles, y mediante la adición de un adicional al final se termina con dos. Los siguientes dos inicializaciones son idénticos:

char str1[6] = "Hello\0";
char str2[6] = { 'H', 'e', 'l', 'l', 'o', '\0', '\0'};

Entonces

char drumReadString[] = "Hello";

es suficiente, y especificando el tamaño de la matriz es opcional cuando se inicializa como este, el compilador de averiguar el tamaño requerido (6 bytes).

2

Al escribir una cadena, que sólo podría ser que también acaba escribir todos los caracteres de una sola vez (en lugar de escribir uno por uno carácter tiempos sizeOfString):

fwrite(drumCString, sizeOfString, 1, fp);

3

A pesar de que no es tan común que un escenario normal PC de escritorio, malloc puede devolver NULL y que se beneficiará de desarrollar un habito de siempre comprobar el resultado porque en sistemas empotrados, consiguiendo NULL no es un resultado poco probable.

char *drumReadString = malloc(sizeof(char) * stringLength);
if (drumReadString == NULL) {
        fprintf(stderr, "drumReadString allocation failed\n");
        return;
}

Usted no escribe la terminación NUL, que no necesita, pero luego hay que pensar en añadir que durante la lectura. es decir malloc StringLength + 1 char, leer caracteres StringLength y añadir un \0 al final de lo que se ha leído.

Ahora, la advertencia habitual: si está escribiendo archivo binario de la manera que está haciendo aquí, usted tiene un montón de suposiciones no que hacen que el formato difícil de puerto, a veces incluso a otra versión del mismo compilador - que he visto alineación predeterminada en cambios struct entre las versiones del compilador.

Algunos más que añadir a paxdiablo y AProgrammer - si se va a utilizar malloc en el futuro, sólo lo hacen desde el principio. Es mejor forma y significa que no tendrá que cambiar de depuración cuando terminado.

Además no estoy viendo totalmente el uso de la corto sin signo, si usted está pensando en escribir un archivo binario, considero que el tipo unsigned char es generalmente de bytes de tamaño, por lo que es muy conveniente para ese propósito.

Basta con retirar su drumReadString y en el fread function.You simplemente utilizar drumReadString en que funcionan como Ganesh mentioned.Because, drumReadString es un array.Array es similar a los punteros que apuntan a la ubicación de memoria directamente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top