传递二维数组作为形参时仅能访问首个字符串的问题求助
二维数组传递与字符串处理问题解析
核心问题定位
你的代码存在多处逻辑错误,导致无法正确访问二维数组的后续元素,具体问题如下:
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
相关产品推荐
相关产品推荐

