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

C语言传递字符串数组给函数从stdin读取时崩溃如何解决?

问题根因与修复方案

错误原因

  • 形参类型不匹配:你在main中定义的char ArrayStrings[MAX_STRINGS][MAX_CHARS_STRING]是连续存储的二维字符数组,作为参数传递给函数时会退化为char (*)[MAX_CHARS_STRING]类型(指向长度为20的字符数组的指针),和你定义的char **二级指针类型完全不兼容。函数内部执行ArrayStr[string_pos]时会把数组中存储的字符内容当做内存地址寻址,直接触发非法内存访问导致崩溃。
  • 使用已废弃的gets函数:gets函数不做输入长度校验,只要输入内容超过数组长度就会触发栈溢出,即使参数类型正确也有极高概率崩溃,该函数在C11标准中已被正式移除。
  • const变量用于定长数组声明不符合标准兼容要求:C标准中const修饰的变量不属于编译期常量,用其声明的数组为变长数组,部分老旧编译器不支持该特性,也容易引发预期外的行为。

修复方案

  1. 将两个长度常量改为宏定义,保证编译期可识别
  2. 修改ReadStrings的形参类型为兼容二维数组的数组指针形式
  3. 替换gets为fgets做安全的输入读取,同时处理可能的换行符和边界问题

修复后可运行代码

#include <stdio.h>
#include <string.h>
// 用宏定义编译期常量
#define MAX_CHARS_STRING 20
#define MAX_STRINGS 5

// 形参改为数组指针类型,匹配二维数组传参的退化类型
int ReadStrings (char (*ArrayStr)[MAX_CHARS_STRING]) {
    int string_pos = 0;
    while (string_pos < MAX_STRINGS) {
        // 使用fgets指定读取长度,避免溢出
        if (fgets(ArrayStr[string_pos], MAX_CHARS_STRING, stdin) == NULL) {
            break;
        }
        // 去除fgets读取到的末尾换行符
        size_t len = strlen(ArrayStr[string_pos]);
        if (len > 0 && ArrayStr[string_pos][len-1] == '\n') {
            ArrayStr[string_pos][len-1] = '\0';
        }
        string_pos++;
    }
    return 1;
}

// 补充WriteStrings实现示例
int WriteStrings (char (*ArrayStr)[MAX_CHARS_STRING]) {
    for (int i = 0; i < MAX_STRINGS; i++) {
        printf("字符串%d: %s\n", i+1, ArrayStr[i]);
    }
    return 0;
}

int main()
{
    int err = 0;
    char ArrayStrings[MAX_STRINGS][MAX_CHARS_STRING] = {0}; // 初始化数组避免垃圾值
    err = ReadStrings(ArrayStrings);
    err = WriteStrings(ArrayStrings);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 02:57:00