Когда я запускаю свою программу, fgets () игнорируется, а scanf() не вводит данные в структуру


Когда я запускаю его, fgets() просто игнорируется, а scanf () не вводит данные в структуру.

Мой код:

#include"stdio.h"
#include"stdlib.h"

typedef struct {
  char nazv[50];
  int numr;
  int date[3];
  int time[2];
} train;

void input(train*rasp,int n);
void print(train*rasp,int n);
void output(train*rasp, int n, int*date, int*time);

main() {
  int n;
  int t[2];
  int d[3];
  printf("How much? ");
  scanf("%d",&n);
  train* rasp=(train*)malloc(n*sizeof(train));
  input(rasp,n);
  printf("Enter date: ");
  for (int date=0;date<3;date++) {
    scanf("%d",&d[date]);
  }
  printf("Enter time: ");
  for (int time=0;time<2;time++) {
    scanf("%d",&t[time]);
  }
  for (int i=0;i<n;i++)
    print(rasp,n);
  output(rasp,n,d,t);
  free(rasp);
  return 0;
}
void input(train*rasp,int n) {
  for (int i=0;i<n;i++) {
    printf("Train #%dn",i+1);
    printf("Enter train's name: ");
    fgets(rasp[i].nazv,50,stdin);
    printf("Enter train's number: ");
    scanf("%d",&rasp[i].numr);
    printf("Enter date: ");
    for (int d=0;d<3;d++) {
      scanf("%d",&rasp[i].date[d]);
    }
    printf("Enter time: ");
    for (int t=0;t<2;t++) {
      scanf("%d",&rasp[i].time[t]);
    }
  }
  printf("nOK.");
}
void print(train*rasp,int n) {
  printf("Name: ");
  printf("%s",rasp[n].nazv);
  printf("nNumber: %d",rasp[n].numr);
  printf("nDate: %d.%d.%d", rasp[n].date[0],rasp[n].date[1],rasp[n].date[2]);
  printf("nTime: %d:%dn", rasp[n].time[0],rasp[n].time);
}
void output(train*rasp,int n,int*date,int*time) {
  for (int i=0;i<n;i++) {
    if (rasp[n].date[2]<date[2])
      continue;
    if (rasp[n].date[2]>date[2]) {
      print(rasp,n);
    } else {
      if (rasp[n].date[1]<date[1])
    continue;
      if (rasp[n].date[1]>date[1]) {
    print(rasp,n);
      } else {
    if (rasp[n].date[0]<date[0])
      continue;
    if (rasp[n].date[0]>date[0]) {
      print(rasp,n);
    } else {
      if (rasp[n].time[0]<time[0])
        continue;
      if (rasp[n].time[0]>time[0]) {
        print(rasp,n);
      } else {
        if (rasp[n].time[1]<=time[1])
          continue;
        print(rasp,n);
      }
    }
      }
    }
  }
}

Функция Input() должна вводить поезда в базу данных. функция output() должна печатать только поезда из базы данных с датой, более поздней, чем указанная ранее пользователем.

1 2

1 ответ:

scanf("%d",&n);

scanf оставляет новую строку, которая отправила входные данные в программу в буфере ввода.

train* rasp=(train*)malloc(n*sizeof(train));
input(rasp,n);

void input(train*rasp,int n) {
  for (int i=0;i<n;i++) {
    printf("Train #%d\n",i+1);
    printf("Enter train's name: ");
    fgets(rasp[i].nazv,50,stdin);

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

    printf("Enter train's number: ");
    scanf("%d",&rasp[i].numr);

Который scanf не удается преобразовать в int.

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

Вы можете очистить буфер

void clear_input_buffer(void) {
    int c;
    while((c = getchar()) != EOF && c != '\n');
    if (c == EOF) {
        // input stream broken, what now?
        exit(EXIT_FAILURE);
    }
}

Или использовать fgets для всех входных данных и использовать sscanfstrtol и друзей) для разбора входных данных.