СПРОСИ ПРОФИ
👍
0
👎 06

Язык Си, бинарные файлы

Добрый день, Уважаемые профи. Какой день бьюсь над этой задачей и все бестолку. Буду очень благодарна за любую помощь. Задание такое:Используя функции и режим меню, создать файл из 10 структур, просмотреть файл, добавить в файл новую информацию и, применяя режим прямого доступа, выполнить задание по своему варианту.Структура имеет вид: фамилия, номер телефона, дата рождения. Внести в начало списка информацию о четырех новых знакомых.

Пробема, конечно же, в добавлении в начало списка. Итак я считываю последнюю строку, отодвигаю ее на следующую и переписываю, освобождая место в начале списка. Все работает безотказно, если каждый раз после добавления новой записи в начало списка выходить из цикла, т.е. добавлять по одной записи за раз. Если сразу делать 4 записи, то в конце списка появляется много пустых записей. Никак не могу от них избавиться.


#include <stdio.h>
#include <conio.h>
#include <string.h>
struct friends {char name[10]; int numb; char bd[11];} n1;
void input(FILE *);
void print(FILE *);
void add(FILE *);
main()

{ char c;

FILE *nf;

while (1)

{

puts(" 1 — NEW");

puts(" 2 — READ");

puts(" 3 — ADD NEW");

puts(" 0 — EXIT");

c=getch();

switch(c)

{ case '1':input(nf);break;

case '2':print(nf);break;

case '3':add(nf);break;

case '0':return 0;

default : puts(" ERROR");

}

}

}
void input(FILE *nf)

{ char ch;

nf=fopen(«file1.dat»,«wb»);

printf(«\n NEW NOTE: \n»);

do

{ printf(«\n NAME: "); scanf(»%s",n1.name);

printf(" PHONE NUMBER +7:«); scanf(»%d",&n1.numb);

printf(" BIRTHDAY: «); scanf(»%s",&n1.bd);

fwrite(&n1,sizeof(n1),1,nf);

printf(«\n EXIT? y/n \n»);

ch=getch();

}
while (ch != 'y');

fclose(nf);

}

void print(FILE *nf)

{ int i;

nf=fopen(«file1.dat»,«rb»);

rewind(nf);

i=1;

fread(&n1,sizeof(n1),1,nf);

while (!feof(nf))

{ printf(«\n %3d NAME %10s PHONE NUMBER +7%6.2d BIRTHDAY %4s», i, n1.name, n1.numb, n1.bd);

fread(&n1,sizeof(n1),1,nf);

i++;

}


getch();


}
void add(FILE *nf)

{
long i;
int am;
char ch;
nf=fopen(«file1.dat»,«rb+»);
am=0;

do{
rewind(nf);

while (!feof(nf)) //до конца файла считываем количество байтов
{fread (&n1, sizeof(n1),1, nf);
am++;
}

for (i = ((am*sizeof(n1))-sizeof(n1));i>=0;i-=sizeof(n1)) { // смещаемся на начало последней строки
fseek(nf,i,0);
fread (&n1, sizeof(n1),1, nf);// читаем
fseek(nf, 0, 1);// с текущей позиции переписываем строку
fwrite(&n1, sizeof(n1),1, nf);
}

printf («\n New note:\n»);
printf («\nNAME:»); scanf («%s», &n1.name);
printf («PHONE NUMBER +7:»); scanf («%d»,&n1.numb);
printf («BIRTHDAY»); scanf («%s», &n1.bd);
fseek(nf,0,0); // перемещаемся на начало файла и пишем
fwrite (&n1,sizeof (n1),1,nf);
printf («\n Finish? y/n»);
ch=getch();}
while (ch!='y');
fclose(nf);
}

программирование обучение     #1   08 май 2022 23:48   Увидели: 19 клиентов, 11 специалистов   Ответить
👍
0
👎 0

Можно попробовать перед каждой операцией чтения данных открывать файл для чтения, читать структуру, потом закрывать, потом открывать уже для записи, и записывать в нужную позицию, потом снова закрывать. Но не исключено, что ошибка в чем-то другом. Можно еще просто прочитать весь файл в память и перезаписать его с добавленной позицией в начале. Стоит использовать больше отладочного вывода для тестов.

👍
0
👎 0

Спасибо большое!

  #4   10 май 2022 00:32   Ответить
👍
+1
👎 1

Ну так в отладчике смотреть надо значения переменных в ходе выполнения, чтобы вовремя отслеживать такие ошибки.
Чему, например, 'am' равно при повторной вставке?

👍
0
👎 0

Спасибо большое!

  #5   10 май 2022 00:32   Ответить
👍
+1
👎 1

Мария, пустые спасибы любого размера тут никого не интересуют. Лучшей благодарностью будет рассказ о том, как последовали совету и что обнаружили в результате.

👍
+1
👎 1

Проверила значение am, оказалось много больше, чем должно быть. Перенесла am=0 внутрь цикла do while, после rewind. Заработало

  #7   19 май 2022 21:49   Ответить

Задайте свой вопрос по программированию
профессионалам

Сейчас онлайн 75 репетиторов по программированию
Получите ответ профи быстро и бесплатно
ASK.PROFI.RU © 2020-2024