能否在二维数组中比较字符串并执行计算?代码运行异常求助
当然可以在二维数组中比较字符串并执行计算,你的程序停止执行是因为代码存在多处未定义行为和逻辑错误,以下是具体问题和修复方案:
一、导致程序停止的直接原因
打印数组的for循环结束后,ctr的值等于line(循环条件为ctr < line,最后一次循环后ctr自增到line),此时fdata[ctr]访问的是数组越界位置(有效索引为0到line-1),后续strcmp(fdata[ctr], fdata[x])会触发内存访问错误,导致程序崩溃或停止。
二、代码中的关键错误及修复
无效的变量更新
代码中的ctr+4;和x+4;仅计算数值但未赋值给变量,变量不会发生变化,需修改为:ctr += 4; x += 4;错误的浮点值转字符串方式
*fdata[ctr + 1] = total;试图将float值直接赋值给字符数组首元素,会导致数据丢失且类型不匹配,需用sprintf将浮点值转为字符串存入数组:sprintf(fdata[ctr + 1], "%.1f", total);错误的空值判断逻辑
fdata[x] == NULL不成立,二维数组的元素是固定大小的字符数组(非指针),无法与NULL比较。若需判断行是否为空,应检查行首字符:if (fdata[x][0] == '\0')函数参数不匹配
remove_dataX_Fquantity和remove_dataX_Fcode的参数声明无法操作二维数组,需修改为二维数组形式:int remove_dataX_Fquantity(char fdata[BSIZE][100], int x); int remove_dataX_Fcode(char fdata[BSIZE][100], int x);调用时直接传入
fdata即可:remove_dataX_Fquantity(fdata, x); remove_dataX_Fcode(fdata, x);错误的循环终止条件
while (fdata[ctr] != NULL)逻辑错误,应改为判断ctr是否在有效行数范围内:while (ctr < line && fdata[ctr][0] != '\0')文件读取的潜在问题
while (!feof(fptr) && !ferror(fptr))易导致最后一行重复读取,建议直接用fgets作为循环条件,并去除换行符避免影响字符串比较:while (fgets(fdata[line], 100, fptr) != NULL && line < BSIZE) { fdata[line][strcspn(fdata[line], "\n")] = '\0'; line++; }
三、修复后的核心逻辑示例
#define BSIZE 1024 char fdata[BSIZE][100]; float total; int line = 0, ctr = 0, x = 4; int remove_dataX_Fquantity(char fdata[BSIZE][100], int x); int remove_dataX_Fcode(char fdata[BSIZE][100], int x); int main() { FILE *fptr; if (fopen_s(&fptr, "Dist.txt", "r") != 0) { perror("Failed to open file"); return 1; } // 改进的文件读取逻辑 while (fgets(fdata[line], 100, fptr) != NULL && line < BSIZE) { fdata[line][strcspn(fdata[line], "\n")] = '\0'; line++; } fclose(fptr); // 打印读取内容 for (ctr = 0; ctr < line; ctr++) { printf("row %d: %s\n", ctr, fdata[ctr]); } ctr = 0; // 重置ctr避免越界 x = 4; // 修复后的循环逻辑 while (ctr < line && x < line) { // 跳过空行 while (ctr < line && fdata[ctr][0] == '\0') ctr++; while (x < line && fdata[x][0] == '\0') x++; if (ctr >= line || x >= line) break; if (strcmp(fdata[ctr], fdata[x]) == 0) { total = atof(fdata[ctr + 1]) + atof(fdata[x + 1]); sprintf(fdata[ctr + 1], "%.1f", total); remove_dataX_Fquantity(fdata, x); remove_dataX_Fcode(fdata, x); printf("Code: %s, Accumulated Quantity: %.1f\n", fdata[ctr], total); ctr += 4; x += 4; } else { x += 4; if (x >= line) { ctr += 4; x = ctr + 4; } } } return 0; } // 示例:将指定行置空实现删除逻辑 int remove_dataX_Fquantity(char fdata[BSIZE][100], int x) { if (x >= BSIZE) return -1; fdata[x][0] = '\0'; return 0; } int remove_dataX_Fcode(char fdata[BSIZE][100], int x) { if (x >= BSIZE) return -1; fdata[x][0] = '\0'; return 0; }
四、额外注意事项
- 测试数据中的空行会被读入数组,处理时需跳过这些空行,避免无效的字符串比较。
- 确保
remove_dataX_Fquantity和remove_dataX_Fcode函数实现符合你的需求(比如是置空行还是移动后续行覆盖目标行)。 - 始终增加数组边界检查,避免越界访问,这是C程序崩溃的常见原因。
内容的提问来源于stack exchange,提问作者Beginner

