#c #fwrite
#c #fwrite
Вопрос:
В моем коде ниже файл записывается правильно, насколько я могу судить. Когда я смотрю в файл, всплывает.dat Я вижу этот поток двоичных ÍÌL@33c@ÍÌÜ@ffFAßOeA^@^@bBf6zE33äCff<83>BÍ̦B
Однако моя программа всегда заканчивает запуском этого оператора if:
if(fread(inputFloats, sizeof(float), LENGTH, binaryFile) < LENGTH)
{
fprintf(stderr, "Problem reading some or all data from %snn", binaryFileName);
return EXIT_FAILURE;
}
Кто-нибудь видит, что я что-то здесь сделал не так? Полный код ниже.
#include <stdlib.h>
#include <stdio.h>
#define LENGTH 10
int main(void)
{
FILE *binaryFile, *textFile;
char *binaryFileName = "floats.dat", *textFileName = "floats.txt";
float floats[LENGTH] = {3.2, 3.55, 6.9, 12.4, 14.332, 56.5, 4003.4, 456.4, 65.7, 83.4};
float inputFloats[LENGTH];
int i;
if((binaryFile = fopen(binaryFileName, "r ")) == NULL)
{
fprintf(stderr, "Problem opening %s", binaryFileName);
}
if(fwrite(floats, sizeof(float), LENGTH, binaryFile) < LENGTH)
{
fprintf(stderr, "Problem writing some or all data to %sn", binaryFileName);
return EXIT_FAILURE;
}
printf("DATA WRITTEN SUCCESSFULLYn");
if(fread(inputFloats, sizeof(float), LENGTH, binaryFile) < LENGTH)
{
fprintf(stderr, "Problem reading some or all data from %snn", binaryFileName);
return EXIT_FAILURE;
}
for(i = 0; i < LENGTH; i )
{
printf("float[%d] = %fn", i, floats[i]);
}
return EXIT_SUCCESS;
}
Комментарии:
1. Существуют ли отдельные позиции файла для чтения и записи в один и тот же файл? Если нет, fread пытается прочитать значения с плавающей запятой за теми, которые вы только что написали. В этом случае используйте
rewind(binaryFile)
.
Ответ №1:
- Вы не работаете с текстовыми данными, поэтому вам следует указать двоичный режим при открытии файла. Используйте
r b
вместоr
- Вам нужно
fseek(binaryFile, 0, SEEK_SET)
«перемотать» файл после записи.rewind
также может быть использовано для этого случая —fseek
позволяет вам размещать указатель чтения / записи там, где вы хотите.
Комментарии:
1. Это идеально, спасибо, Эрик. Есть ли какие-либо недостатки в использовании более простого вызова, такого как то, что @steabert использовал ниже — rewind (двоичный файл)?
2. Кроме того, я просто играл, и теперь, когда это работает, я все еще получаю тот же результат, даже при использовании ‘r ‘. Является ли указание ‘r b’ отказоустойчивым для вашего кода в случае, если он перенесен на другую систему, возможно, с другой реализацией fopen, которая не допускает использование двоичных файлов при открытии с помощью ‘r ‘?
3. @Chris Paynter:
rewind
здесь все в порядке. Однако вы должны знать обfseek
.r b
гарантирует, что никто не работает со встроеннымn
— это может быть не нужно на вашей платформе
Ответ №2:
FILE
Структура хранит запись о том, на какую часть файла она в данный момент указывает. Поскольку вы только что выполнили запись в binaryFile
, указатель на файл находится в конце того, что вы написали.
Поэтому вам необходимо перемотать файл назад, используя fseek(binaryFile, 0, SEEK_SET);
перед чтением.
Ответ №3:
Вы забыли перемотать файл перед его чтением:
rewind(binaryFile);
Ответ №4:
Когда вы заканчиваете запись в файл, указатель на ФАЙЛ находится в его конце, поэтому, конечно, если вы попытаетесь прочитать, это не сработает. Попробуйте использовать fseek
для перемещения указателя в начало файла перед чтением.
Пожалуйста, избегайте этого :
if((binaryFile = fopen(binaryFileName, "r ")) == NULL) {
и предпочитаю это:
binaryFile = fopen(binaryFileName, "rb ");
if(!binaryFile) {
Комментарии:
1. Нет ничего плохого в присваивании в состоянии, когда оно так же четко читаемо, как здесь.
2.
=
при условном переходе это того не стоит. Лучше перестраховаться, чем потом сожалеть.