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

打印字符串时缺失首字符问题求助(附C语言代码)

问题分析与解决方案

问题原因

  1. 重复调用getchar()导致首字符丢失:每次录入员工ID前调用getchar(),第一次调用会清除scanf遗留的换行符,但后续循环中,getchar()会直接读取用户输入的第一个字符(此时缓冲区为空,getchar()会等待输入并拿走首字符),导致后续gets只能读取剩余部分,最终打印时缺失首字符。
  2. 内存分配不足:员工ID是C字符串,需要额外1字节存储结束符'\0',当前代码仅分配size字节,会触发缓冲区溢出,引发未定义行为。
  3. gets函数不安全:gets无法限制读取长度,极易导致缓冲区溢出,已被C标准废弃。

修复后的代码

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

int main(void)
{
    int size, i, j;
    printf("enter no. of employee\n");
    scanf("%d", &j);
    printf("size of employee id\n");
    scanf("%d", &size);
    
    // 仅调用一次getchar,清除scanf残留的换行符
    getchar();

    // 分配内存时预留字符串结束符的空间
    char *m[j];
    for (i = 0; i < j; i++) {
        m[i] = malloc((size + 1) * sizeof(char));
        if (m[i] == NULL) {
            printf("Memory allocation failed\n");
            return 1;
        }
    }

    for (i = 0; i < j; i++) {
        printf("Enter employee id of %d: ", i + 1);
        // 用fgets替代gets,限制读取长度避免溢出
        fgets(m[i], size + 1, stdin);
        // 移除fgets读取到的换行符
        m[i][strcspn(m[i], "\n")] = '\0';
    }

    printf("employee id are:\n");
    for (i = 0; i < j; i++) {
        puts(m[i]);
        free(m[i]); // 释放内存避免泄漏
    }

    return 0;
}

修改说明

  • 移除循环内的getchar(),仅在最后一个scanf后调用一次,清除缓冲区残留的换行符。
  • malloc时分配size + 1字节,为字符串结束符预留空间。
  • 用fgets替代gets,指定最大读取长度,避免缓冲区溢出;同时用strcspn去掉fgets读取到的换行符。
  • 修正main函数的返回值为标准的int类型,添加内存分配失败检查和内存释放步骤。

内容的提问来源于stack exchange,提问作者vatsal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 05:45:43