Pergunta

Eu quero armazenar cordas em um arquivo binário, juntamente com um monte de outros dados, im usando o código abaixo (quando eu usá-lo para valer as cordas será malloc) eu posso escrever para o arquivo. Ive olhou para ele em um editor hexadecimal. Im não tem certeza im escrevendo o terminador nulo corretamente (ou se eu preciso). quando eu li para trás para fora eu recebo o mesmo comprimento de cadeia que eu armazenados, mas não a string. o que estou fazendo de errado?

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); 
Foi útil?

Solução

Você está fazendo de errado durante a leitura. você colocar o & para a variável ponteiro é por isso que dá falha de segmentação.

Eu removi que ele funciona bem e retorna Olá corretamente.

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

Outras dicas

Eu vejo um par de questões, algumas problemática, alguns estilística.

  • Você realmente deve testar os valores de retorno de malloc, fread e fwrite já que é possível que a alocação pode falhar, e nenhum dado pode ser lido ou escrito.
  • sizeof(char) é sempre 1, não há necessidade de multiplicar por ele.
  • A matriz "Hello\0" personagem é, na verdade, 7 bytes de comprimento. Você não precisa adicionar um terminador nulo supérfluo.
  • Eu prefiro o char x[] = "xxx"; idioma em vez de especificar um comprimento definido (a menos que queira uma série mais longa do que a string é claro).
  • Quando você fread(&drumReadString ..., na verdade você está substituindo o ponteiro , e não a memória que ele aponta. Esta é a causa de sua queda. Deve ser fread(drumReadString ....

Um casal de dicas:

1

A terminação \0 está implícito em qualquer cadeia de aspas duplas, e adicionando um adicional de, no final você acaba com dois. As duas inicializações seguintes são idênticos:

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

Assim

char drumReadString[] = "Hello";

é suficiente, e dependendo do tamanho da matriz é opcional quando é inicializado como este, o compilador irá descobrir o tamanho necessário (6 bytes).

2

Ao escrever uma string, você pode muito bem basta escrever todos os caracteres de uma só vez (em vez de escrever um por vezes um sizeOfString personagem):

fwrite(drumCString, sizeOfString, 1, fp);

3

Apesar de não tão comum para um cenário normal pc desktop, malloc pode retornar NULL e você será beneficiado com o desenvolvimento de um habbit de sempre verificar o resultado porque em ambientes incorporados, obtendo NULL não é um resultado improvável.

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

Você não escrever o NUL terminar, você não precisa, mas então você tem que pensar sobre a adição de que durante a leitura. ie malloc StringLength + 1 char, ler caracteres StringLength e adicionar um \0 no final do que foi lido.

Agora, o aviso habitual: se você estiver escrevendo arquivo binário do jeito que você está fazendo aqui, você tem muitas suposições não declaradas que tornam a sua formato difícil de porta, às vezes até mesmo para outra versão do mesmo compilador - Eu vi alinhamento padrão em struct muda entre versões do compilador.

Alguns mais a acrescentar à paxdiablo e AProgrammer - se você estiver indo para usar malloc no futuro, apenas fazê-lo a partir do ir buscar. É melhor forma e significa que você não terá de depuração quando passar.

Além disso eu não estou vendo totalmente o uso do short sem sinal, se você está pensando em escrever um arquivo binário, consideram que o tipo char não assinado é geralmente de tamanho em bytes, o que torna muito conveniente para o efeito.

Você simplesmente remover seu & drumReadString na function.You fread simplesmente usar drumReadString nessa função como Ganesh mentioned.Because, drumReadString é um array.Array é semelhante aos ponteiros que apontam para o local da memória diretamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top