使用指针实现城市名按字母排序时遇数组类型赋值错误的解决方法
修复C语言编译错误:assignment to expression with array type
此前完成过从指定格式文件读取城市名并按字母顺序单列输出的练习,现尝试用指针实现时出现编译错误,错误提示为error: assignment to expression with array type。以下是未完成的代码,需修复编译错误(注:代码尚未完成,仅需解决编译问题,可忽略最后两个for循环):
#include <stdio.h> #include <stdlib.h> #include <string.h> #define N 100 typedef struct Ordered { char str[N]; } ordered; int main() { int i = 0, j, n, m; char c1[20], c2[20], c3[20]; ordered *v; FILE *file; file = fopen("file", "r"); if (file == NULL) { printf("Error in the file..."); exit(1); } fscanf(file, "%d %d", &n, &m); int k = n * m; v = (ordered *) malloc(k * sizeof(ordered)); if (v == NULL) { fprintf(stderr, "Memory allocation error.\n"); exit(EXIT_FAILURE); } while (fscanf(file, "%s %s %s", c1, c2, c3) && i < k) { v[i].str = (char *) malloc((strlen(c1) + 1) * sizeof(char)); v[i + 1].str = (char *) malloc((strlen(c2) + 1) * sizeof(char)); v[i + 2].str = (char *) malloc((strlen(c3) + 1) * sizeof(char)); if (v == NULL) { if (v[i].str == NULL || v[i + 1].str == NULL || v[i + 2].str == NULL) { fprintf(stderr, "Memory allocation error.\n"); exit(EXIT_FAILURE); } } strcpy(v[i].str, c1); strcpy(v[i + 1].str, c2); strcpy(v[i + 2].str, c3); i=+3; } char s[20]; for (i = 1; i < k; i++) { s = v[i].str; } printf("\n\n"); for (i = 0; i < n * m; i++) printf("%s\n", v[i].str); return 0; }
错误原因及修复方案:
结构体数组成员不能直接赋值指针
- 结构体
Ordered中的str是固定大小的字符数组(char str[N]),数组名是常量指针,不能作为左值被赋值。原代码中v[i].str = (char *)malloc(...)属于非法操作。 - 修复:不需要额外为
str分配内存(数组已有N=100的空间),直接用strcpy将读取到的字符串复制到数组中即可,删除所有针对v[i].str的malloc语句。
- 结构体
数组不能直接用
=赋值- 最后for循环中
s = v[i].str错误,C语言中数组无法直接通过赋值运算符复制,需用strcpy函数完成复制。
- 最后for循环中
其他逻辑错误(非编译错误但需修正)
i=+3是语法错误,应为i += 3,否则每次循环都会将i重置为3,导致逻辑异常。- 内存分配后的空指针检查逻辑错误:原代码先判断
v == NULL(但v已在前面检查过),且检查顺序颠倒,应在malloc后立即检查每个指针是否为NULL。
修复后的核心代码片段:
方案1:保留结构体数组成员(无需动态分配字符串)
// 读取循环部分修复 while (fscanf(file, "%s %s %s", c1, c2, c3) && i < k) { // 直接复制字符串到结构体数组的str成员,无需malloc strcpy(v[i].str, c1); strcpy(v[i + 1].str, c2); strcpy(v[i + 2].str, c3); i += 3; // 修正为i +=3 } // 最后for循环修复(若保留) char s[20]; for (i = 1; i < k; i++) { strcpy(s, v[i].str); // 用strcpy代替直接赋值 }
方案2:修改结构体为指针成员(动态分配字符串)
如果希望用指针动态分配字符串内存,可修改结构体定义:
typedef struct Ordered { char *str; } ordered; // 读取循环部分修改 while (fscanf(file, "%s %s %s", c1, c2, c3) && i < k) { v[i].str = malloc(strlen(c1) + 1); v[i+1].str = malloc(strlen(c2) + 1); v[i+2].str = malloc(strlen(c3) + 1); // 检查每个malloc是否成功 if (!v[i].str || !v[i+1].str || !v[i+2].str) { fprintf(stderr, "Memory allocation error.\n"); exit(EXIT_FAILURE); } strcpy(v[i].str, c1); strcpy(v[i+1].str, c2); strcpy(v[i+2].str, c3); i +=3; }
内容的提问来源于stack exchange,提问作者Severjan Lici
相关产品推荐
相关产品推荐

