C语言二维数组赋值及相关文件读取代码纠错咨询
C语言二维字符串数组赋值方法及代码纠错
首先得明确:C语言里二维char数组(也就是字符串数组)没法直接用=赋值,因为数组名是地址常量,不能直接赋值。正确的做法是用字符串拷贝函数,比如strcpy(或者更安全的strncpy)来逐个复制字符串元素。
接下来我逐个拆解你代码里的问题,然后给出修正后的完整版本:
代码中的核心问题
- 变量名错误:你定义了
char goods[200][100];,但代码里却用了未定义的item[i],得把item替换成goods才行。 - 字符串赋值逻辑错误:
temp[x][x] = qty[i];完全不对——qty[i]是一个字符串(char*类型),而temp[x][x]只是单个char字符,根本没法直接赋值。应该用strcpy(temp[x], qty[i]);来复制整个字符串。 - feof循环陷阱:
while (!feof(fp))会导致最后一次循环重复读取(因为feof只有在读取到文件末尾之后才会置位),正确的循环条件应该是判断fscanf的返回值,确认是否成功读取了3个字段。 - 数组越界风险:原代码里
temp[x + 1][x + 1]的访问逻辑完全错误,一是x递增时x+1很可能超出数组范围,二是你要比较的应该是当前新加入的temp[x]和前一个元素temp[x-1](毕竟x+1的位置还没赋值)。另外,原代码没判断文件是否打开成功,空指针操作会直接导致程序崩溃。 - 循环变量递增时机错误:原代码不管
fscanf是否成功读取,i都会递增,容易导致数组越界,得把i++放在fscanf成功读取的分支里。
修正后的完整代码
#include <stdio.h> #include <string.h> int main() { FILE *fp = fopen("fileA.txt", "r"); // 先判断文件是否打开成功,避免空指针操作 if (fp == NULL) { perror("Failed to open file"); return 1; } int i = 0; char name[200][100]; char goods[200][100]; char qty[200][100]; char temp[200][100]; int x = 0; // 用fscanf的返回值判断是否成功读取3个字段,避免feof陷阱 while (fscanf(fp, "%[^,] , %[^,] , %s ", name[i], goods[i], qty[i]) == 3) { if (strcmp(goods[i], "Football") == 0) { // 安全复制字符串到temp数组,避免缓冲区溢出 strncpy(temp[x], qty[i], sizeof(temp[x]) - 1); // 手动添加字符串结束符,确保字符串合法 temp[x][sizeof(temp[x]) - 1] = '\0'; // 比较当前Football数量和前一个的大小(这里假设你要做相邻排序) if (x > 0) { // 注意:如果要比较数值大小,需要先把字符串转成整数,比如用atoi // 下面是字符串字典序比较,若要数值比较,替换成atoi转换后的逻辑即可 if (strcmp(temp[x], temp[x - 1]) > 0) { // 示例交换逻辑,可根据你的需求修改 char swap_buf[100]; strcpy(swap_buf, temp[x]); strcpy(temp[x], temp[x - 1]); strcpy(temp[x - 1], swap_buf); } } x++; } i++; } fclose(fp); // 记得关闭文件,避免资源泄漏 return 0; }
额外提示
- 如果你要比较的是数量的数值大小(不是字符串的字典序),得把
temp里的字符串转换成整数,比如用atoi()或者更安全的strtol():int current_qty = atoi(temp[x]); int prev_qty = atoi(temp[x-1]); if (current_qty > prev_qty) { // 这里写你的数值比较后的逻辑 } - 用
strncpy代替strcpy是为了防止源字符串长度超过目标数组的大小,避免缓冲区溢出,安全性更高。
内容的提问来源于stack exchange,提问作者Cc Li




