Почему в бинарном файле отображаются буквы вместо чисел?
Мне необходимо записать элементы массива (целые числа) в один бинарный файл, затем считать оттуда эти элементы, изменить массив и результат (вещественные числа) записать в другой бинарный файл, но вот что-то во второй файл записывается какой-то бред, или не бред. Может кто-то объяснить, что это значит, потому что в интернете ничего толкового не нашел? Осуществил вывод не только в файл, но и на экран, и на экране ответ верный, а вот в файле смущает запись на коде ascii.
#include <stdio.h>
#include <stdlib.h>
#include<conio.h>
int main()
{
int n, i, a[10];
float b[10];
FILE* f, * f2;
f = fopen("prob1.dat", "rb+");
printf("Enter n=");
scanf("%i", &n);
fwrite(&n, sizeof(int), 1, f);
for (i = 0; i < n; i++)
{
printf("\a(%i)= ", i);
scanf("%i", &a[i]);
}
for (i = 0; i < n; i++)
{
printf("%3i", a[i]);
fwrite(&a[i], sizeof(int), 1, f);
}
fclose(f);
f = fopen("prob1.dat", "rb");
f2 = fopen("prob2.dat", "wb+");
for (int i = 0; i < n; i++)
{
fread(&a[i], sizeof(int), 1, f);
}
for (int i = 0; i < n; i++)
{
b[i] = a[i];
if (a[i] > 0)
{
if (a[i] % 4 == 0)
{
b[i] = 0.1;
}
}
}
for (int j = 0; j < n; j++)
{
fwrite(&b[j], sizeof(float), 1, f2);
}
printf("\n");
for (int j = 0; j < n; j++)
{
printf("%4.1f ", b[j]);
}
fclose(f);
printf("\n");
system("pause");
return 0;
}
Ответы (2 шт):
Бинарный файл представляет из себя последовательность произвольных байтов. Текстовый файл является частным случаем бинарного файла, в котором символы закодированы в виде последовательности байтов с помощью какой-то кодировки.
Всего различных байтов 256: от 00 до FF в шестандцатиричной системе счисления. Любые файлы состоят из байтов. И то, какого рода данные находятся в файле, определяется исключительно тем, как мы их интерпретируем. Мы не можем взять произвольный бинарный файл и прочитать его, если не знаем, какова его структура. Потому что байты в файле могут быть текстовыми данными, целыми числами, числами с плавающей точкой или иметь какую-то более сложную структуру.
Поэтому, если мы будем пытаться прочитать бинарный файл как текстовый, скорее всего, некоторые его байты будут соответствовать каким-то символам из таблицы ASCII (или из какой-то другой таблицы). И это нормально. В частности, байт CC соответстует русской букве Н из кодироваки Windows-1251. Суть в том, что не надо читать файл как текстовый, если он не текстовый.
В отличие от целых чисел бинарное представление чисел с плавающей точкой несколько сложнее. Чтобы проверить корректность записанных в файл чисел, можно воспользоваться, например, одним из сервисов для конвертации hex-данных или какой-нибудь программой с требуемым функционалом. Чаще всего на современных системах тип float занимает 4 байта.
Итак, можно видеть, что первые 4 байта из вашего файла соответствуют значению 0.1 типа float:
Следующие 4 байта соответствуют значению 1.0 типа float:
Заметьте, если интерпретировать эти байты по-другому, как другой тип, то получаются совсем другие значения. Но делать это бессмысленно.
во второй файл записывается какой-то бред
Почему Вы решили, что содержимое этого файла - бред?!
Я написал крохотный конвертер тех трёх значений, которые видны в приведённой распечатке файла:
#include <stdio.h>
int main(int argc, char *argv[]) {
union convert {
unsigned int i;
float f;
} a;
a.i = 0x3DCCCCCD;
printf("%f\n", a.f);
a.i = 0x3F800000;
printf("%f\n", a.f);
a.i = 0x40000000;
printf("%f\n", a.f);
}
И результат работы этой программульки показался мне вполне разумным:
$ ./a.out
0.100000
1.000000
2.000000
Не забывайте только, про big-endian и его зеркальное отражение :-)


