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

C语言中字符串数组使用gets函数的输入异常问题排查

问题分析与解决

你的代码存在两个致命问题,直接导致了输入异常:

1. 未为单个字符串分配内存

你仅给字符串指针数组str分配了空间(malloc(sizeof(char*)*n)),但每个str[i]都是未初始化的野指针,指向的内存地址完全随机。直接用gets(str[i])往里面写数据会触发未定义行为——前两次输入可能侥幸成功,但很快就会破坏程序内存结构,导致后续输入无法正常进行,甚至直接崩溃。

2. gets函数已被废弃且不安全

gets不检查输入长度,极易造成缓冲区溢出;同时它会直接读取输入流中的换行符,虽然后你用%*c吃掉了scanf后的换行,这部分没问题,但gets本身的设计缺陷依然是隐患。


修复后的代码示例

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

// 你的自定义函数示例
void func(char **str, int n) {
    for (int i = 0; i < n; i++) {
        printf("第%d个字符串:%s\n", i+1, str[i]);
    }
}

int main() {
    int n, i;
    printf("Number of strings is: ");
    scanf("%d%*c", &n);

    // 分配指针数组内存
    char **str = malloc(sizeof(char*) * n);
    if (str == NULL) { // 检查内存分配是否成功
        perror("malloc failed");
        return 1;
    }

    for (i = 0; i < n; i++) {
        printf("Input %d. string: ", i+1);
        // 为每个字符串分配内存,这里假设最大长度100,可按需调整
        str[i] = malloc(100 * sizeof(char));
        if (str[i] == NULL) {
            perror("malloc failed for string");
            // 释放已分配的内存,避免泄漏
            for (int j = 0; j < i; j++) {
                free(str[j]);
            }
            free(str);
            return 1;
        }
        // 用fgets替代gets,指定缓冲区大小避免溢出
        fgets(str[i], 100, stdin);
        // 去掉fgets读取到的末尾换行符
        str[i][strcspn(str[i], "\n")] = '\0';
    }

    // 调用自定义函数处理字符串数组
    func(str, n);

    // 释放所有内存,避免泄漏
    for (i = 0; i < n; i++) {
        free(str[i]);
    }
    free(str);

    return 0;
}

关键修复点说明

  • 为每个str[i]单独分配内存,确保有合法的存储空间存放输入字符串。
  • 用fgets替代gets,fgets可指定缓冲区大小,避免溢出;同时手动去除读取到的换行符(fgets会把输入时的回车也读入字符串)。
  • 增加内存分配失败的检查逻辑,避免程序崩溃。
  • 使用完内存后逐一释放,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 01:07:14