c - 为什么 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”不够用还是其他原因?
非常感谢。
解决方案
你需要让你的琴弦更长。
char Bulan_str[4]
不够大,您无法输入 4 位数字。它需要足够大以容纳数字、换行符和空终止符。
当您拨打电话fgets(Bulan_str, sizeof(Bulan_str), stdin)
并键入一个 4 位号码时,它会将号码的前 3 个字符读入字符串。输入行的其余部分留在输入缓冲区中。
然后下次您调用fgets()
时,它将从缓冲区中读取该行的其余部分,因此它不会等待您输入任何内容。
因此,声明所有输入字符串至少比某人可以输入的最大可能值大 2 个字节。
推荐阅读
- arrays - 如何在 bash 脚本中声明 n+1 个元素的数组?
- c# - 在 GeckoFx C# 中挂钩所有请求的响应正文
- python - 我该如何解决这个问题?
- react-native - Cocoapods,pod 安装错误,我该如何解决?
- api - API | 硬币 | 用户/退出 | 无效参数 (POST)
- python - 函数内的 Python 入口小部件
- deployment - 如何在 bitbucket 管道中用部署变量替换 .env 文件占位符
- java - 如何将@Generated 注释添加到delombok 代码?
- python - 在 Pandas 中加载带有管道分隔字段的 .txt 文件时,如何用撇号 (') 替换双引号 (")?
- javascript - 无法将 mini-css-extract 插件安装到我的项目中