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

传递二维数组作为形参时仅能访问首个字符串的问题求助

二维数组传递与字符串处理问题解析

核心问题定位

你的代码存在多处逻辑错误,导致无法正确访问二维数组的后续元素,具体问题如下:

1. 文件读取函数readFileFormat的错误

  • while(!feof(nounFile))误用:该写法会导致文件读取结束后额外执行一次循环,造成数组元素重复或错误填充。
  • 冗余变量与参数错误:cols变量完全多余,fgets的第一个参数直接用words[rows]即可(words[rows]本身是指向第rows行首地址的指针),无需&words[rows][cols]。
  • 返回值不匹配:函数声明为void,但内部却写了return 1;,属于语法错误。

2. 复数处理函数determinePlurals的错误

  • 打印目标错误:所有printf中使用words,这是二维数组的首地址(等价于words[0]),导致每次仅打印第一个字符串,应改为words[rows]。
  • 循环变量重复递增:for循环本身会自动执行rows++,但每个分支里又手动添加rows++,导致每次循环跳过一行,无法遍历所有元素。
  • 字符串越界风险:判断最后1个或2个字符时,未先检查字符串长度是否足够,空字符串或长度为1的字符串会导致strlen(words[rows])-2为负数,引发越界访问。

修正后的代码

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

#define ROWS 50
#define COLS 50

// 修改返回值为int,用于返回错误状态
int readFileFormat(char words[ROWS][COLS]);
void determinePlurals(char words[ROWS][COLS]);

int main()
{
    char words[ROWS][COLS] = {0}; // 初始化数组,避免垃圾值干扰

    if (readFileFormat(words) != 0)
    {
        return 1;
    }
    determinePlurals(words);

    return 0;
}

int readFileFormat(char words[ROWS][COLS])
{
    FILE* nounFile;
    // 用fopen_s返回值判断文件是否打开成功
    if (fopen_s(&nounFile, "plural.txt", "r") != 0)
    {
        printf("Error reading file; try again.\n");
        return 1;
    }

    int rows = 0;
    // 用fgets返回值判断读取状态,替代while(!feof)
    while (rows < ROWS && fgets(words[rows], COLS, nounFile) != NULL)
    {
        // 去除换行符
        words[rows][strcspn(words[rows], "\n")] = '\0';
        rows++;
    }
    
    fclose(nounFile);
    return 0;
}

void determinePlurals(char words[ROWS][COLS])
{
    const char* iesEnd = "ies";
    const char* esEnd = "es";
    const char* sEnd = "s";

    for (int rows = 0; rows < ROWS; ++rows)
    {
        // 跳过空字符串,终止无效行遍历
        if (words[rows][0] == '\0')
        {
            break;
        }

        size_t len = strlen(words[rows]);
        printf("%s: ", words[rows]);

        if (len >= 1 && words[rows][len - 1] == 'y')
        {
            words[rows][len - 1] = '\0';
            // 确保追加时不溢出缓冲区
            strncat(words[rows], iesEnd, COLS - strlen(words[rows]) - 1);
            printf("%s\n", words[rows]);
        }
        else if (len >= 2 && 
                 (strcmp(words[rows] + len - 2, "ch") == 0 ||
                  strcmp(words[rows] + len - 2, "ss") == 0 ||
                  strcmp(words[rows] + len - 2, "sh") == 0) ||
                 (len >=1 && words[rows][len -1] == 'x'))
        {
            strncat(words[rows], esEnd, COLS - strlen(words[rows]) - 1);
            printf("%s\n", words[rows]);
        }
        else
        {
            strncat(words[rows], sEnd, COLS - strlen(words[rows]) - 1);
            printf("%s\n", words[rows]);
        }
        // 移除手动rows++,由for循环自动处理
    }       
}

额外说明

  • 初始化数组char words[ROWS][COLS] = {0};可避免未赋值元素的垃圾值,方便判断有效行。
  • 使用strncat时,通过COLS - strlen(words[rows]) - 1控制最大追加长度,防止缓冲区溢出。
  • 修正了原代码中对"x"结尾的判断逻辑,改为单独判断单个字符'x',符合复数规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 12:30:40