C语言实现int键与string值动态数组遇问题,求技术指导
课程作业问题解答:动态数组实现键值操作
疑问解答
1. 是否需要先大字符串转小char数组?
不需要。userStr[1000]作为临时缓冲区没问题,但你代码里的savStr写法完全错误——savStr[strL];不是重新分配数组长度,只是一个无效表达式,而且变长数组(VLA)声明后无法修改长度。正确做法是:读取到userStr后,直接根据strlen(userStr)+1(加1用于存储字符串终止符\0)分配内存给单个字符串,再把userStr复制过去。
2. 动态数组实现是否正确?如何扩展索引?
你当前的实现完全错误,核心问题是valueArry的类型不对:
- 键的数组
keyArry是int*(存储int的动态数组),这个是对的; - 值的数组需要存储多个字符串,每个字符串是
char*,所以值的数组应该是char**(指向指针的指针,即字符串指针数组),而不是char*(单个字符串)。
扩展索引的逻辑:
- 初始化时给数组分配初始容量(比如8),同时记录当前容量和已使用的元素数
curr; - 当
curr == 当前容量时,用realloc把容量翻倍(比如从8变16),扩容后更新容量值。
3. 内存分配是否正确?
keyArry的分配是对的:calloc(8, sizeof(int))分配了8个int的内存并初始化为0;valueArry的分配完全错误:你用calloc(8, sizeof(char))只分配了8个字符的内存,根本存不下7个字符串。正确的分配应该是calloc(8, sizeof(char*)),即分配8个字符串指针的内存,每个指针后续再单独分配字符串内存。
输出异常的原因与修复
原因
你把valueArry当成了char数组,执行strcpy(&valueArry[curr], &savStr)时,是从valueArry的第curr个字符位置开始复制字符串。比如:
- 第一个字符串
one复制到位置0-2; - 第二个字符串
two复制到位置1-3,覆盖了one的第1、2位,变成ott...; - 后续每个字符串都从当前
curr位置开始覆盖前面的内容,导致输出时从第i位读字符串,出现重叠截断的异常。
修复步骤
- 修正
main函数参数:int main(int argc, char **argv)(你写成了char **argc); - 把
valueArry改为char**类型,正确分配指针数组内存; - 去掉无效的
savStr,直接为每个读取到的字符串分配内存; - 实现动态扩容逻辑;
- 修正变量名错误(比如
cuserNumber改为userNumber); - 最后释放所有分配的内存,避免泄漏。
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char **argv) { int userNumber; char userStr[1000]; // 临时缓冲区,存储读取到的字符串 FILE *fp = fopen("values.txt", "r"); if (!fp) { // 检查文件是否打开成功 perror("Failed to open file"); return 1; } // 键的动态数组 int *keyArry = calloc(8, sizeof(int)); // 值的动态数组:存储字符串指针 char **valueArry = calloc(8, sizeof(char*)); int curr = 0; // 当前已存储的元素数 int capacity = 8; // 当前数组容量 while (fscanf(fp, "%d,%s", &userNumber, userStr) != EOF) { // 动态扩容:当元素数达到容量时,翻倍容量 if (curr == capacity) { capacity *= 2; keyArry = realloc(keyArry, capacity * sizeof(int)); valueArry = realloc(valueArry, capacity * sizeof(char*)); if (!keyArry || !valueArry) { perror("Realloc failed"); return 1; } } // 为当前字符串分配内存(+1存储'\0') char *str = malloc(strlen(userStr) + 1); strcpy(str, userStr); // 存入数组 keyArry[curr] = userNumber; valueArry[curr] = str; printf("%d - %s\n", userNumber, str); curr++; } fclose(fp); // 输出验证 printf("\n--- 存储结果验证 ---\n"); for (int i = 0; i < curr; i++) { printf("%d - %s\n", keyArry[i], valueArry[i]); } // 释放内存:先释放每个字符串,再释放数组本身 for (int i = 0; i < curr; i++) { free(valueArry[i]); } free(keyArry); free(valueArry); return 0; }
代码说明
- 动态扩容:每次元素数达到容量时,用
realloc翻倍容量,避免频繁扩容; - 内存管理:每个字符串单独分配内存,最后要依次释放,再释放指针数组和键数组;
- 错误检查:增加了文件打开、内存分配的错误检查,避免程序崩溃;
- 灵活存储:不再依赖固定长度的数组,能处理任意数量的键值对(只要内存足够)。
内容的提问来源于stack exchange,提问作者user20384189
相关产品推荐
相关产品推荐

