Чтение пользовательской информации из двоичного файла в связанный список - PullRequest
0 голосов
/ 03 октября 2018

Я пытался прочитать узел из двоичного файла, но он прочитал бы только первый (я думаю). При запуске load () он показывает следующее: Вывод только выполнения загрузки

Обратите внимание, что два printf были только для проверки правильности его чтения или нет. В финальной версии его не будет, как и в выражениях scanf () в void save ().Там просто загрузить и сохранить данные в файл

КОД:

#include <stdio.h>
#include <stdlib.h>
#include<conio.h>

//function prototypes
struct user* newuser();
void save();
void load();
void display();


struct user
{
    char uname[50];
    char upass[15];
    int uid;
    int listofbooks[3];
    struct user *next;
};
struct user *ustart=NULL;

/*struct book
{
    int bid;
    char topic[15];
    char aut[50];
    char bname[50];
    struct book *l;
    struct book *r;
};  */

struct user* newuser()
{
  struct user *u;
  u=(struct user* )malloc(sizeof(struct user))  ;
  return(u);
};

/*void save()
{
 struct user *ul;
 struct user *t;
 int i;
 FILE *fp;

 ul=newuser();
 if(ustart==NULL)
 {
     ustart=ul;
     ul->next=NULL;

     printf("Enter Name\n");
   scanf("%s",ul->uname);
   printf("Enter Password\n");
   scanf("%s",ul->upass);
   printf("Enter ID\n");
   scanf("%d",&ul->uid);
   for(i=0;i<4;i++)
   {
       ul->listofbooks[i]=0;
   }

   if( ( fp=fopen("ham.txt","wb+") )==NULL )
  {
      printf("FIle opening error");
      getch();
  }
   fwrite(ul,sizeof(struct user),1,fp);
   fclose(fp);
 }
 else
 {
   t=ustart;
   while(t->next!=NULL){
    t=t->next;
   }
   //change
   t->next=ul;
   ul->next=NULL;
   printf("Enter Name\n");
   scanf("%s",ul->uname);
   printf("Enter Password\n");
   scanf("%s",ul->upass);
   printf("Enter ID\n");
   scanf("%d",&ul->uid);
   for(i=0;i<4;i++)
   {
       ul->listofbooks[i]=0;
   }

    if( ( fp=fopen("ham.txt","rb+") )==NULL )
  {
       printf("FIle opening error");
   }
    fseek(fp, 0, SEEK_END);

   fwrite(ul,sizeof(struct user),1,fp);
   fclose(fp);
 }
}*/



void load()
{
 int i;
 long int j;
 struct user *ul;
 FILE *fp;

 ul=newuser();
 ustart=ul;

  if( ( fp=fopen("ham.txt","rb+") )==NULL )
  {
      printf("FIle opening error");
      getch();
 }
  fseek(fp,0,SEEK_END);
  j=ftell(fp);
  j=( j/sizeof(struct user)) ;

   for(i=0;i<j;i++)
   {
    fseek(fp, (sizeof(struct user) * i), SEEK_SET);
    fread(ul,sizeof(struct user),1,fp);
    printf("\nName:%s",ul->uname);
    printf("\nPassword:%s",ul->upass);
    ul=ul->next;
   }

   fclose(fp);

}

void display()
{
    struct user *t;
    int i;
    t=ustart;
    while(t!=NULL)
    {
    printf("Name:%s\nPassword:%s\nID:%d\nList of books",t->uname,t->upass,t->uid);
    for(i=0;i<4;i++){
    printf("%d",t->listofbooks[i]);
    }
  }
}

void main()
{
   int i,lp=1;
   do{
    printf("\n1.load\n3.exit\n2.display\n4.save\nEnter choice:");
    scanf("%d",&i);
    switch(i)
    {
        case 1: load();
        break;

    case 2:display();
    break;

    case 3:lp=0;
    printf("Exiting");
    break;

    //case 4:save();
    //break;

    default:printf("invalid");
    break;
    }
     }while(lp);

    }

Пожалуйста, помогите найти ошибку в коде. Я проверил много сайтов, пробовал много разных способовитерация fread (), но безрезультатно.

Я не думаю, что есть проблема с fwrite, так как члены строки присутствуют, когда я открываю текстовый файл. (void save () находится в форме комментария, как я хочуиспользовать его только для изменения базы данных / файла.)

Я использую code: blocks. Я использую C около полутора лет, но довольно плохо знаком с файловыми функциями и связанным списком. Любые советы по улучшениюкод?

1 Ответ

0 голосов
/ 03 октября 2018

Вам нужно создавать нового пользователя на каждой итерации цикла при чтении пользователей из файла:

Удалить эти строки (очень непонятно, вы хотите читать j пользователей, но выделяете память только для одного):

ul=newuser();
ustart=ul;

Добавить эти изменения:

   user* previousUser = NULL; // to hold previous user from file

   for(i=0;i<j;i++)
   {
        ul=newuser(); // create new user with every iteration
        if (!i)
            ustart = ul; // set head of list

        fseek(fp, (sizeof(struct user) * i), SEEK_SET);
        fread(ul,sizeof(struct user),1,fp);
        printf("\nName:%s",ul->uname);
        printf("\nPassword:%s",ul->upass);

        ul->next = NULL; // set next to NULL for current user
        if (previousUser)
            previousUser->next = ul; // update previous user to point to current one
        previousUser = ul;
   }
...