Как удалить содержимое структуры после ее сохранения в файле bin? - PullRequest
0 голосов
/ 05 мая 2019

Я пишу код для добавления информации о пациенте в файл.Я использую компилятор gcc, который поставляется с Linux, для компиляции моего кода.Например, если я написал «Доу» для отчества первого пациента в файле и если я добавляю в файл другого пациента без отчества, автоматически второе имя другого пациента будет «Доу».Есть ли способ очистить структуру так, чтобы середина была равна нулю?

Я ожидаю midname = "", но фактический вывод - midname = "Doe"

void addpatient()
{
  system("clear");
  char ending; // end do while loop
  char temp;
  int check;
  char choice;
  FILE *infile, *checkid;
  if((infile= fopen("hospital.bin","ab"))== NULL)
  {
    printf("Error! opening file. File may not exist or is corrupted");
    exit(1);
  }
  checkid = fopen("hospital.bin","rb");
  do
  {
    while (fread(&input, sizeof(input), 1, checkid))
    {
      check = input.ID;
    }
    check++;
    input.ID = check;
    printf("Last ID used:%d\n", check);
    printf("Insert new patient\'s name\n");
    scanf("%s",input.name);
    printf("Does patient has a middle name? y/n\n");
    scanf(" %c", &choice);
    if((choice =='y') || (choice=='Y'))
    {
      printf("Insert new patient\'s middle name\n");
      scanf("%s",input.midname);
    }
    printf("Insert new patient\'s surname\n");
    scanf("%s",input.surname);
    printf("Insert new patient\'s address\n");
    scanf("%c",&temp);
    fgets(input.address,300,stdin);
    printf("Insert new patient\'s telephone number\n");
    scanf("%d",&input.telephone);
    printf("Insert new patient\'s mobile phone number\n");
    scanf("%d",&input.mobile);
    fwrite(&input,sizeof(input),1,infile);
    printf("Do you want to continue? y/n\n");
    scanf(" %c",&ending);
    system("clear");
  }while((ending=='Y') || (ending=='y'));
  fclose(infile);
  fclose(checkid);
}

1 Ответ

0 голосов
/ 05 мая 2019

Например, если я написал «Доу» для отчества первого пациента в файле, и если я добавил в файл другого пациента без отчества, автоматически второе имя другого пациента будет «Доу».

просто замените

 if((choice =='y') || (choice=='Y'))
 {
   printf("Insert new patient\'s middle name\n");
   scanf("%s",input.midname);
 }

от

if((choice =='y') || (choice=='Y'))
{
  printf("Insert new patient\'s middle name\n");
  scanf("%s",input.midname);
}
else
   input.midname[0] = 0;

Есть ли способ очистить структуру, чтобы середина была равна нулю?

Существует только одно необязательное поле, но если вы действительно хотите это сделать, просто заполните все от 0 до memset(&input, 0, sizeof(input));, например.


Обратите внимание, что сохранение данных с помощью fwrite(&input,sizeof(input),1,infile); не позволит правильно прочитать файл в случае, если размер полей или порядок байтов не совпадают, или если позже вы добавите / удалите / измените поля (полей), поэтому это не портативный Сохраняйте поля одно за другим, используя их внешнее представление, чтобы быть переносимыми, начиная с номера формата, чтобы знать, как читать файл, если вы измените определения позже.

Я также рекомендую вам проверить значение, возвращаемое scanf , чтобы узнать, прочитали ли вы правильное значение.

В настоящее время, если пользователь вводит слишком длинную строку, вы будете выводить ее из поля с неопределенным поведением, ограничьте размер входных данных для строк.


(редактировать после вашего замечания)

Есть ли у вас ссылки на рекомендации, которые вы сказали для scanf

Если я хорошо понимаю, что у вас есть, например, char name[50], даже маловероятно, если пользователь введет слово, содержащее не менее 50 символов scanf("%s", input.name) пишет, по крайней мере, 51 символ, выходящий из поля. Например, выполните scanf("%49s", input.name), чтобы не рисковать неопределенным поведением (49 вместо 50, чтобы иметь место для нулевого символа, заканчивающего строку)

Обратите внимание, что вы не можете ввести сложное имя, содержащее пробелы, используя scanf .

и для сохранения полей по одному

используете ли вы для записи , но fprintf , конечно, делая это, вы не можете прочитать уже существующие значения по fread , и вам нужно использовать, например, fscanf

Также вы (попробуйте) повторить

while (fread (& input, sizeof (input), 1, checkid)) { check = input.ID; }

также каждый раз, когда вы добавляете новый элемент, вам это не нужно, кроме как перед тем, как войти в цикл для добавления новых записей

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...