Home > Back-end >  Why fgets skips input after convert char to int in looping?
Why fgets skips input after convert char to int in looping?

Time:10-16

I'm curious why fgets skips input after convert char to int in looping? How can I solved it?

Here's the code below:

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

struct TanggalLahir {
  int Tanggal;
  int Bulan;
  int Tahun;
};

struct Dosen {
  char NoDosen[255];
  char Nama[255];
  struct TanggalLahir tgllahir;
};

int main() {

  struct Dosen dosen[5];
  
  char NoDosen[255];
  char Nama[255];

  int Tanggal;
  char Tanggal_str[4];
  
  int Bulan;
  char Bulan_str[4];
  
  int Tahun;
  char Tahun_str[8];

  printf("Pengisian data dosen \n");
  for (int i = 0; i < 2; i  ) {
    printf("Nomor Dosen: ");
    fgets(NoDosen, sizeof(NoDosen), stdin);
    NoDosen[strcspn(NoDosen, "\n")] = '\0';
    strcpy(dosen[i].NoDosen, NoDosen);

    printf("Nama: ");
    fgets(Nama, sizeof(Nama), stdin);
    Nama[strcspn(Nama, "\n")] = '\0';
    strcpy(dosen[i].Nama, Nama);

    printf("Tanggal: ");
    fgets(Tanggal_str, sizeof(Tanggal_str), stdin);
    Tanggal = strtol(Tanggal_str, NULL, 10);
    dosen[i].tgllahir.Tanggal = Tanggal;

    printf("Bulan: ");
    fgets(Bulan_str, sizeof(Bulan_str), stdin);
    Bulan = strtol(Bulan_str, NULL, 10);
    dosen[i].tgllahir.Tanggal = Tanggal;

    printf("Tahun: ");
    fgets(Tahun_str, sizeof(Tahun_str), stdin);
    Tahun = strtol(Tahun_str, NULL, 10);
    dosen[i].tgllahir.Tahun = Tahun;
  }

  printf("Pengisian data dosen selesai. \n");
  for (int i = 0; i < 2; i  ) {
    printf("Nomor Dosen: %s \n", dosen[i].NoDosen);
    printf("Nama: %s \n", dosen[i].Nama);
    printf("Tanggal Lahir \n");
    printf("Tanggal: %d \n", dosen[i].tgllahir.Tanggal);
    printf("Bulan: %d \n", dosen[i].tgllahir.Bulan);
    printf("Tahun: %d \n", dosen[i].tgllahir.Tahun);
  }
}

Is that because I do conversion char to int with strtol() function? If so, how can I solved it?

Here's the example output program in my terminal.

~/Learning/learn-c 
❯ ./data_dosen
Pengisian data dosen 
Nomor Dosen: D1234
Nama: Kresna
Tanggal: 6
Bulan: Tahun: 1995
Nomor Dosen: Nama: Nuna
Tanggal: 8
Bulan: Tahun: 1996
Pengisian data dosen selesai. 
Nomor Dosen: D1234 
Nama: Kresna 
Tanggal Lahir 
Tanggal: 6 
Bulan: 0 
Tahun: 199 
Nomor Dosen: 5 
Nama: Nuna 
Tanggal Lahir 
Tanggal: 8 
Bulan: 0 
Tahun: 199 

As you can see that field "Bulan" and "Nomor Dosen" skipped by program. What I expect that input field "Bulan" and "Nomor Dosen" don't skip by fgets so the expected output program like below:

~/Learning/learn-c 
❯ ./data_dosen
Pengisian data dosen 
Nomor Dosen: D1234
Nama: Kresna
Tanggal: 6
Bulan: 5
Tahun: 1995
Nomor Dosen: D33345
Nama: Nuna
Tanggal: 8
Bulan: 7
Tahun: 1996
Pengisian data dosen selesai. 
Nomor Dosen: D1234 
Nama: Kresna 
Tanggal Lahir 
Tanggal: 6 
Bulan: 5 
Tahun: 1995
Nomor Dosen: 5 
Nama: Nuna 
Tanggal Lahir 
Tanggal: 8 
Bulan: 7 
Tahun: 1996

I'm curious is that because of my data type "Bulan" is not enough or maybe else?

Thanks a lot.

CodePudding user response:

You need to make your strings longer.

char Bulan_str[4] isn't large enough for you to enter a 4-digit number. It needs to be large enough for the number, the newline, and the null terminator.

When you call fgets(Bulan_str, sizeof(Bulan_str), stdin) and type a 4-digit number, it will read the first 3 characters of the number into the string. The rest of the input line are left in the input buffer.

Then the next time you call fgets(), it will read the rest of that line from the buffer, so it doesn't wait for you to type anything.

So declare all your input strings to be at least 2 bytes larger than the largest possible value someone could enter.

  • Related