fscanf读取后superVisorNames内外打印值不一致问题求助
问题
使用fscanf读取文件中的主管姓名与评分到结构体变量时,循环内打印superVisorNames值正常,但循环外打印出现字符串叠加异常,superVisorRating值始终正常。
核心代码片段
int read_Supervisors(char fileName[], spec *specread){ int i=0; FILE *supervisors = fopen(fileName, "r"); if(supervisors == NULL){ printf("Error opening supervisors input file name %s", fileName); }else while(fscanf(supervisors, "%s %d", &specread->superVisorNames[i], &specread->superVisorRating[i]) !=EOF){ printf("before y %s y \n", &specread->superVisorNames[i]); i++; } for(int j=0; j<i;j++){ printf("After y %s y\n", &specread->superVisorNames[j]); } fclose(supervisors); return i; }
程序输出
before y Bob y before y Sally y before y Jian y before y Hecctor y After y BSJHecctor y After y SJHecctor y After y JHecctor y After y Hecctor y
读取文件内容
Bob 67 Sally 78 Jian 69 Hecctor 89
已尝试谷歌搜索、更换循环逻辑、修改文件内容、扩大数组容量等调试手段,仍未定位问题,寻求问题原因及解决办法。
问题原因
问题出在结构体中superVisorNames的定义上——你大概率把它声明成了单个字符数组而非字符串数组,比如:
typedef struct { char superVisorNames[20]; // 错误:单个字符数组,所有姓名会挤在同一块内存 int superVisorRating[10]; } spec;
这种情况下,每次fscanf写入姓名时,都会从数组起始位置开始覆盖部分内存,但后续姓名的长度更长时,前面的字符不会被完全覆盖,加上没有正确的字符串终止符\0(或者被后续写入覆盖),导致打印时会从当前索引位置一直读到内存中第一个\0,出现字符串叠加的现象。
循环内打印正常是因为刚写入完当前姓名,此时后续内存还未被覆盖,刚好能读到正确的终止符;循环外是所有姓名都写入完成,内存被多次覆盖,终止符位置混乱,就出现了叠加。
解决办法
把结构体中的superVisorNames定义为二维字符数组(即字符串数组),确保每个姓名有独立的内存空间:
typedef struct { char superVisorNames[10][20]; // 正确:最多存10个姓名,每个姓名最长19字符+1个终止符 int superVisorRating[10]; } spec;
同时注意:
- 确保数组的第一维度(姓名数量)和第二维度(单姓名长度)足够容纳你的数据,避免缓冲区溢出
- 使用
fscanf时,建议限制读取的字符数,比如%19s,防止单个姓名过长导致缓冲区溢出:
这里不需要加fscanf(supervisors, "%19s %d", specread->superVisorNames[i], &specread->superVisorRating[i])&,因为superVisorNames[i]本身就是指向该字符串首地址的指针。
内容的提问来源于stack exchange,提问作者Daniel Boos
相关产品推荐
相关产品推荐

