C语言循环中char转int后fgets跳过输入的原因及解决方法
问题原因分析
你的问题和strtol函数完全无关,是两个代码错误共同导致的:
- 第一个是结构体字段赋值错误,Bulan字段根本没有被正确赋值
- 第二个是输入缓冲区长度不足+换行残留,导致后续
fgets直接读取到缓冲区残留的换行符,表现为被跳过
具体错误点
- Bulan赋值错误
你处理完Bulan的输入转换后,又错误地给Tanggal字段重复赋值,结构体里的Bulan字段自始至终都没有被赋值,所以输出永远是0:
// 你原来的错误代码 Bulan = strtol(Bulan_str, NULL, 10); dosen[i].tgllahir.Tanggal = Tanggal; // 这里写错了,应该给Bulan赋值
- 缓冲区太小且未处理残留换行
你定义的Tanggal_str[4]、Bulan_str[4]只能容纳最多3个有效字符,如果输入的数字+换行超过3个字符,剩余的字符(包括换行)就会留在输入缓冲区里,下一次fgets会直接读取这些残留内容,不需要用户输入,表现为被跳过。
另外你只处理了NoDosen和Nama的换行清除,日期相关的输入都没有做换行和残留处理,也会导致问题。比如你输入的1995只被读到199,剩下的"5\n"会被下一次循环的Nomor Dosen的fgets读取,所以你第二次的Nomor Dosen输出是5。
解决方法
1. 修复赋值错误
把Bulan处理后的赋值语句改成正确的字段:
Bulan = strtol(Bulan_str, NULL, 10); dosen[i].tgllahir.Bulan = Bulan; // 改成Bulan字段
2. 扩大缓冲区+统一处理输入残留
把日期相关的缓冲区改大到足够容纳输入,并且每次读完fgets后统一清除换行和残留内容:
// 把缓冲区改大,避免长度不足 char Tanggal_str[16]; char Bulan_str[16]; char Tahun_str[16]; // 每次fgets后都执行以下逻辑清除换行 Tanggal_str[strcspn(Tanggal_str, "\n")] = '\0';
3. 完整修改后的代码
#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[16]; int Bulan; char Bulan_str[16]; int Tahun; char Tahun_str[16]; 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_str[strcspn(Tanggal_str, "\n")] = '\0'; Tanggal = strtol(Tanggal_str, NULL, 10); dosen[i].tgllahir.Tanggal = Tanggal; printf("Bulan: "); fgets(Bulan_str, sizeof(Bulan_str), stdin); Bulan_str[strcspn(Bulan_str, "\n")] = '\0'; Bulan = strtol(Bulan_str, NULL, 10); dosen[i].tgllahir.Bulan = Bulan; // 修复赋值错误 printf("Tahun: "); fgets(Tahun_str, sizeof(Tahun_str), stdin); Tahun_str[strcspn(Tahun_str, "\n")] = '\0'; 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); } return 0; }
内容的提问来源于stack exchange,提问作者Kresna Satya
相关产品推荐
相关产品推荐

