Dificuldade em gravar arquivo binário [RESOLVIDO]

1. Dificuldade em gravar arquivo binário [RESOLVIDO]

Steve
Steve

(usa Slackware)

Enviado em 30/03/2020 - 18:47h

As 2 formas abaixo não estão de verdade gravando o arquivo como binário!
Possuo no meu PC arquivos binários, e não posso ler eles com um simples editor de textos!
Porém o meu exemplo, qualquer editor de textos consegue ler os arquivos sem nenhuma dificuldade!

Onde estou errando? Porque não está gravando o arquivo como binário?

 #include <stdio.h>
#include <string.h>
int main(void) {
FILE *File_Creation = fopen("Arquivo_Binario.bin", "wb");
fputs("Linha 1\nLinha 2\nLinha 3\nLinha 4\nLinha 5\nLinha 6\nLinha 7\n", File_Creation);
fclose(File_Creation);

FILE *File_Creation2 = fopen("Arquivo_Binario2.bin", "wb");
char Text[] = "Linha 1\nLinha 2\nLinha 3\nLinha 4\nLinha 5\nLinha 6\nLinha 7\n";
fwrite(Text, sizeof(Text), strlen(Text), File_Creation2);
fclose(File_Creation2);
}



  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 31/03/2020 - 03:59h

Steve escreveu:

As 2 formas abaixo não estão de verdade gravando o arquivo como binário!


Qual sistema operacional você está usando, e qual editor de textos?

De modo geral, a distinção entre arquivos de texto ou arquivos binários, pelo menos do que diz respeito a programas em C, é qual a maneira de separar uma linha da linha seguinte. No mundo UNIX, arquivos texto são separados com um único caráter, '\n', que é o mesmo caráter usado internamente pelo C como indicador de fim de linha. Desse modo, para um programa em C rodando numa máquina UNIX ou Linux, arquivos texto ou arquivos binários têm o mesmo comportamento. No Windows, no entanto, o fim de linha é indicado no arquivo como um par de caracteres, "\r\n" (nesta ordem), de modo que é necessária uma conversão da marca de fim de linha entre o arquivo e a representação lógica interna do C na hora de ler, e vice-versa na hora de gravar. No mundo Apple (pelo menos antes do MacOS X (agora macOS) e iOS; não sei neles), a marca de fim de linha usada em arquivos é '\r', que também tem de ser convertida de/para '\n' ao gravar a partir de/ler para o programa em C. E outros sistemas têm outras variações.

Então, se o seu programa (que tem um erro, sim, mas de outra natureza; vou falar sobre ele mais tarde) está rodando numa maquina UNIX, o arquivo produzido como se fosse um arquivo texto é o comportamento esperado, pois não há distinção entre binário e texto. E se o editor de textos for um editor de textos típico do UNIX ou um editor de texto capaz de tratar arquivos com notações de fim de linha diferentes, independentes do sistema, então está explicada a questão.

Se seu programa estiver rodando no Windows, mesmo assim você pode não conseguir enxergar o problema se o editor de textos for flexível quanto à marca de fim de linha.

Possuo no meu PC arquivos binários, e não posso ler eles com um simples editor de textos!
Porém o meu exemplo, qualquer editor de textos consegue ler os arquivos sem nenhuma dificuldade!

Onde estou errando? Porque não está gravando o arquivo como binário?
 #include <stdio.h>
#include <string.h>
int main(void) {
FILE *File_Creation = fopen("Arquivo_Binario.bin", "wb");
fputs("Linha 1\nLinha 2\nLinha 3\nLinha 4\nLinha 5\nLinha 6\nLinha 7\n", File_Creation);
fclose(File_Creation);

FILE *File_Creation2 = fopen("Arquivo_Binario2.bin", "wb");
char Text[] = "Linha 1\nLinha 2\nLinha 3\nLinha 4\nLinha 5\nLinha 6\nLinha 7\n";
fwrite(Text, sizeof(Text), strlen(Text), File_Creation2);


O erro está na linha acima. Com fwrite(), o segundo argumento é o tamanho em bytes de cada elemento do array indicado pelo primeiro argumento, e o terceiro argumento é uma contagem do número de elementos a serem escritos. Desse modo, a quantidade total de bytes escritos deveria ser o produto do segundo argumento com o terceiro. Mas note que, do jeito como você fez, você multiplicou o tamanho total do array (incluindo o terminador nulo ao final da string, o que, pela minha contagem falível e cheia de sono, dá 57 bytes) pelo comprimento aproveitável da string, que é 56. Então você tentou gravar 3192 (57×56) bytes a partir de um array que tem apenas 57 elementos de um byte cada, o que lhe dá uma grande chance de estar invadindo memória inválida, e um programa que é candidato a dar erros imprevisíveis.

A forma de corrigir isso é, lembrando que o segundo elemento é um medidor de tamanho de cada elemento do array, deixar isso explícito na hora de invocar a função.
fwrite(Text, sizeof Text[0], strlen(Text), File_Creation2); 


   fclose(File_Creation2);
}




... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)





Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts