You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言循环中char转int后fgets跳过输入的原因及解决方法

问题原因分析

你的问题和strtol函数完全无关,是两个代码错误共同导致的:

  • 第一个是结构体字段赋值错误,Bulan字段根本没有被正确赋值
  • 第二个是输入缓冲区长度不足+换行残留,导致后续fgets直接读取到缓冲区残留的换行符,表现为被跳过

具体错误点

  1. Bulan赋值错误
    你处理完Bulan的输入转换后,又错误地给Tanggal字段重复赋值,结构体里的Bulan字段自始至终都没有被赋值,所以输出永远是0:
// 你原来的错误代码
Bulan = strtol(Bulan_str, NULL, 10);
dosen[i].tgllahir.Tanggal = Tanggal; // 这里写错了,应该给Bulan赋值
  1. 缓冲区太小且未处理残留换行
    你定义的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 14:27:01