简体   繁体   中英

I got an error trying to get input in a structure in c and fgets() doesn't solve it

I happen to have a problem getting the input fror my structure i had this problem with gets() I read answers of some questions and used fgets() but i still have the same problem. Can someone please help me

#include < stdio.h > 
#include < string.h >
#include < stdlib.h > 
#include < conio.h >
  struct liber {
    char titulli[50];
    char autori[20];
    char kategoria[20];
    char id[8]; //structure for books
    int kopje;
  }
libra[50];
/*this is another structure meant to be used for clients bu i havent used it yet :)*/
struct klient {
  char emri[20];
  char mbiemri[20];
  char tel[13];
  char id[8];
}
klient[20];

int nr = 0;

void shtoliber() {
  int i, n = 0; //the function that adds the book in file
  FILE * flib;
  flib = fopen("libra.dat", "wb");
  if (flib == NULL) {
    printf("\nGabim ne hapjen e file!!");
    getch();
    exit(1);
  }
  printf("\n\tShkruani numrine librave qe doni te shtoni: ");
  scanf("%d", & n);
  for (i = 0; i < n; i++) {
    printf("\nTitulli: ");
    fgets(libra[nr].titulli, 50, stdin);
    printf("\nAutori: ");
    fgets(libra[nr].autori, 20, stdin);

    printf("\nKategoria: ");
    fgets(libra[nr].kategoria, 20, stdin);
    printf("\nID: ");
    fgets(libra[nr].id, 10, stdin);
    printf("\nKopje: ");
    scanf("%d", & libra[nr].kopje);
    printf("\n*****************\n");
    fwrite( & libra[nr], sizeof(struct liber), 1, flib);
    printf("\nLibri u regjistrua.\n\v");
    nr++;

  }
  fclose(flib);
}

void kerko_titulli() { //this function is used to search books
  FILE * flib;
  flib = fopen("libra.dat", "rb");
  if (flib == NULL) {
    printf("Gabim ne leximin e file!!");
    return;
  }

  printf("\nKerkim sipas autorit: ");
  char v_autori[50];
  printf("\nJepni autorin e librit qe kerkoni: ");
  scanf("%s", v_autori); {
    nr = 0;
    while (fread( & libra[nr], sizeof(struct liber), 1, flib) == 1);
    if (strcmp(v_autori, libra[nr].autori) == 0) {
      printf("\n\nLibri u gjet : ");
      printf("\nTitulli: ");
      puts(libra[nr].titulli);
      printf("\nAutori:");
      puts(libra[nr].autori);
      printf("\nKategoria:");
      puts(libra[nr].kategoria);
      printf("\nID:");
      puts(libra[nr].id);
      exit(1);
      nr++;
    }
  }
  fclose(flib);
}

void menu() {
  printf("  \t*********************");
  printf("  Detyre Kursi");
  printf("  *********************");
  printf("\n1. Shto libra");
  printf("\n2. kerko libra");
  printf("\ne Exit");
  printf("\n\nZgjedhja: ");

}
int main() {
  char z;
  do {
    menu();
    scanf("%d", & z);
    if (z == 1) shtoliber();
    else if (z == 2) kerko_titulli();

  }
  while (z != 'e' && z != 'E' && z != 27);
}

Output :

Shkruani numrin e librave qe doni te shtoni: 1 Titulli: Autori:_

it won't get the first input of titulli: After i have declared the number of books i want to add it immediately asks for the second input without getting the first.

Mixing calls to scanf and fgets is a bad idea. The reason is that scanf will only consume a portion of a line, leaving the remainder of the line for the next fgets . The remainder is typically just the newline character, so the next fgets reads a blank line.

The solution is to read every line with fgets and then use sscanf to extract information from the line. For example, the following two lines:

printf("\n\tShkruani numrine librave qe doni te shtoni: ");
scanf("%d",&n);

should be changed to:

printf("\n\tShkruani numrine librave qe doni te shtoni: ");
char line[256];
if (fgets(line, sizeof(line), stdin) == NULL) {
    // handle error
}
if (sscanf(line, "%d", &n) != 1) {
    // handle error
}

And yes, the code does need to check the return value from every fgets and sscanf , because they can and will fail when the user input is invalid.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM