Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: Есть вот такой текст программы:
Код :
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//Ячейка хранения
typedef struct
{
unsigned int Number; //Номер записи
unsigned int Length1;
unsigned int Length2;
unsigned int Length3;
} tdata_len;
//Сохранение данных в файл
//Параметр:
// Item - одна ячейка хранения
void SaveToFile(tdata_len * Item)
{
FILE * file;
if ((file = fopen("data.dat", "a"))==NULL)
printf("Не могу открыть файл для записи.");
else
{
fwrite(Item, sizeof(tdata_len), 1, file);
fclose(file);
}
};
//Чтение данных о строке из файла и вывод на экран
//Возвращаемое значение - количество ячеек хранения в файле
int ReadFromFile1()
{
FILE * file;
tdata_len * Item;
int Count = 0;
if ((file = fopen("data.dat", "r"))==NULL)
printf("Не могу открыть файл для чтения.");
else
{
Item = (tdata_len *) malloc(sizeof(tdata_len));
while (!feof(file))
{
fread(Item, sizeof(tdata_len), 1, file);
printf("Номер ячейки : %d\n", Item->Number);
printf("Длина 1 : %d\n", Item->Length1);
printf("Длина 2 : %d\n", Item->Length2);
printf("Длина 3 : %d\n", Item->Length3);
printf("------------------------\n");
Count++;
};
fclose(file);
free(Item);
}
return Count;
};
int main()
{
tdata_len * mycell;
int i = 0;
int Count = 0;
srand(time(NULL));
mycell = (tdata_len *) malloc(sizeof(tdata_len));
//Файла пока не существует. Вводим новые данные
for (i=1;i<4;i++)
{
//Заполнение данных
mycell->Number = i;
mycell->Length1 = rand();
mycell->Length2 = rand();
mycell->Length3 = rand();
//Запись данных в файл
SaveToFile(mycell);
};
//Читаем данные из файла и выводим на экран
Count = ReadFromFile1();
free(mycell);
return 0;
}
Номер ячейки : 1 Длина 1 : 18336 Длина 2 : 10247 Длина 3 : 2159 ------------------------ Номер ячейки : 2 Длина 1 : 5070 Длина 2 : 6043 Длина 3 : 22372 ------------------------ Номер ячейки : 3 Длина 1 : 16295 Длина 2 : 13428 Длина 3 : 8190 ------------------------ Номер
ячейки : 3 Длина 1 : 16295 Длина 2 : 13428 Длина 3 : 8190 ------------------------
Вопрос такой: почему функция ReadFromFile1() последняя ячейка №3 выводится 2 раза (хотя файл имеет размер 3*16 байт = 48, т.е. записано ровно три ячейки)?
Здравствуйте, sir Henry! Потому, что проверку на EOF надо делать после чтения, а не перед. Так у Вас получается, что данные не считаны(остались от предыдущего цикла), но встретился конец файла и программа вывела данные, которых нет.
Код :
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//Ячейка хранения
typedef struct
{
unsigned int Number; //Номер записи
unsigned int Length1;
unsigned int Length2;
unsigned int Length3;
} tdata_len;
//Сохранение данных в файл
//Параметр:
// Item - одна ячейка хранения
void SaveToFile(tdata_len * Item)
{
FILE * file;
if ((file = fopen("data.dat", "a")) == NULL)
printf("Не могу открыть файл для записи.");
else
{
fwrite(Item, sizeof (tdata_len), 1, file);
fclose(file);
}
};
//Чтение данных о строке из файла и вывод на экран
//Возвращаемое значение - количество ячеек хранения в файле
int ReadFromFile1()
{
FILE * file;
tdata_len * Item;
int Count = 0;
if ((file = fopen("data.dat", "r")) == NULL)
printf("Не могу открыть файл для чтения.");
else
{
Item = (tdata_len *) malloc(sizeof (tdata_len));
fread(Item, sizeof (tdata_len), 1, file);
while (!feof(file))
{
printf("Номер ячейки : %d\n", Item->Number);
printf("Длина 1 : %d\n", Item->Length1);
printf("Длина 2 : %d\n", Item->Length2);
printf("Длина 3 : %d\n", Item->Length3);
printf("------------------------\n");
Count++;
fread(Item, sizeof (tdata_len), 1, file);
};
fclose(file);
free(Item);
}
return Count;
};
int main()
{
tdata_len * mycell;
int i = 0;
int Count = 0;
srand(time(NULL));
mycell = (tdata_len *) malloc(sizeof (tdata_len));
//Файла пока не существует. Вводим новые данные
for (i = 1; i < 4; i++)
{
//Заполнение данных
mycell->Number = i;
mycell->Length1 = rand();
mycell->Length2 = rand();
mycell->Length3 = rand();
//Запись данных в файл
SaveToFile(mycell);
};
//Читаем данные из файла и выводим на экран
Count = ReadFromFile1();
free(mycell);
return 0;
}
Код :
Номер ячейки : 1
Длина 1 : 678671864
Длина 2 : 2097842989
Длина 3 : 1266140926
------------------------
Номер ячейки : 2
Длина 1 : 1400430739
Длина 2 : 1258691281
Длина 3 : 248056681
------------------------
Номер ячейки : 3
Длина 1 : 393117925
Длина 2 : 463589343
Длина 3 : 911030439
------------------------
Консультировал: Micren (Профессор)
Дата отправки: 15.05.2012, 19:43
Вы слишком рано проверяете конец файла. Он же начинает возвращать 1 только после попытки чтения дальше конца файла, и у вас получается лишняя итерация со старыми данными Правильно будет проверить сразу после fread():
Код :
for (;;) {
fread(...);
if (feof(file)) break;
/* работа с результатом */
}
Но только сам fread() тоже возвращает осмысленное значение (количество прочитанных элементов), так что понятнее написать как-то так:
Код :
while(fread (Item, sizeof (*Item), 1, file) > 0) {
/* работа с результатом */
}
Консультировал: Хватов Сергей (Академик)
Дата отправки: 15.05.2012, 19:47
5
нет комментария ----- Дата оценки: 16.05.2012, 03:46
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались.
Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора -
для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение.
Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал,
который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом.
Заходите - у нас интересно!