首页 > 解决方案 > 为什么 fgets 在循环中将 char 转换为 int 后会跳过输入?

问题描述

我很好奇为什么 fgets 在循环中将 char 转换为 int 后会跳过输入?我该如何解决?

下面是代码:

#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);
  }
}

那是因为我用strtol()函数将 char 转换为 int 吗?如果是这样,我该如何解决?

这是我终端中的示例输出程序。

~/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 

如您所见,程序跳过了“Bulan”和“Nomor Dosen”字段。我期望输入字段“Bulan”和“Nomor Dosen”不会被 fgets 跳过,因此预期的输出程序如下所示:

~/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

我很好奇是因为我的数据类型“Bulan”不够用还是其他原因?

非常感谢。

标签: cfgets

解决方案


你需要让你的琴弦更长。

char Bulan_str[4]不够大,您无法输入 4 位数字。它需要足够大以容纳数字、换行符和空终止符。

当您拨打电话fgets(Bulan_str, sizeof(Bulan_str), stdin)并键入一个 4 位号码时,它会将号码的前 3 个字符读入字符串。输入行的其余部分留在输入缓冲区中。

然后下次您调用fgets()时,它将从缓冲区中读取该行的其余部分,因此它不会等待您输入任何内容。

因此,声明所有输入字符串至少比某人可以输入的最大可能值大 2 个字节。


推荐阅读