C语言中fgets获取的buffer无法正确存入字符数组问题求助
问题分析与解决:C语言读取文件姓名数据异常的问题
问题原因解析
你的代码在存储姓名时存在几个关键错误,导致所有索引都指向最后一个姓名:
- 赋值运算符误用:
name[index1] == each;使用了相等比较运算符==而非赋值运算符=,这导致name数组里的指针根本没有被正确赋值。 - 局部数组生命周期问题:
each是while循环内的局部字符数组,每次循环迭代时该数组内存会被重复覆盖,且循环结束后内存会被释放。即便改成赋值,所有name指针也会指向同一块内存,最终仅保留最后一次写入的内容。 - 数组初始化语法错误:
char each[4550] = strncpy(each,buffer,sizeof(buffer));;不符合C语言语法,C不允许用函数返回值初始化数组,且strncpy的使用完全多余,还存在多余分号。 - 打印方式错误:
printf("%s",name);直接传递指针数组名,实际传递的是数组首元素地址,但未遍历数组元素,且此时数组指针要么未赋值,要么指向失效内存。
修正方案
针对以上问题,通过以下方式修正代码:
- 使用
strdup函数为每个姓名分配独立堆内存,确保每个指针指向唯一持久的内存空间。 - 修正赋值运算符,将
==改为=。 - 移除多余的
each数组,直接处理buffer后复制。 - 遍历
name数组打印所有姓名,同时处理内存释放避免泄漏。
修正后的代码
#include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> int main(int argc, char *argv[]) { FILE *fPointer; int bufferLength = 255; char buffer[255]; char *name[255]; double floatie[100]; int number[100]; int count = 0; int index1 = 0; // 改为从0开始,符合数组索引习惯 int index2 = 0; int index3 = 0; // 增加参数检查与文件打开失败判断 if(argc < 2){ fprintf(stderr, "请传入文件名参数\n"); return 1; } fPointer = fopen(argv[1],"r"); if(fPointer == NULL){ perror("打开文件失败"); return 1; } while(fgets(buffer,bufferLength,fPointer)){ // 去除换行符 buffer[strcspn(buffer, "\n")] = 0; // 去除字符串开头的空格(可选,按需保留) char *trimmed = buffer; while(isspace((unsigned char)*trimmed)) trimmed++; if(count == 0){ // 分配内存并复制字符串 name[index1] = strdup(trimmed); index1++; count++; } else if(count ==1){ floatie[index2] = atof(trimmed); index2++; count++; } else if(count ==2){ number[index3] = atoi(trimmed); index3++; count = 0; } } // 打印所有姓名并释放内存 for(int i=0; i<index1; i++){ if(name[i] != NULL){ printf("姓名[%d]: %s\n", i+1, name[i]); free(name[i]); } } fclose(fPointer); return 0; }
额外说明
strdup会自动分配足够内存存储字符串,使用后需用free释放,避免内存泄漏。- 新增参数检查与文件打开失败判断,提升代码健壮性。
- 可选的开头空格去除逻辑,适配你提供的文件格式,不需要可直接删除。
- 数组索引从0开始,避免浪费数组首个元素空间。
内容的提问来源于stack exchange,提问作者Zhong Andy
相关产品推荐
相关产品推荐

