如何用fscanf读取逗号分隔文件?读取异常问题排查
fscanf读取逗号分隔文件的问题排查与原理说明
一、fscanf处理逗号分隔文件的工作原理
fscanf的%[^,]格式符作用是扫描并读取所有字符,直到遇到逗号为止,读取完成后,格式串里的逗号会匹配输入中的逗号(相当于跳过这个分隔符)。需要注意两个关键点:
%[^,]属于字符串格式符,不会自动跳过前导空白,如果输入里逗号前后有空格,会直接把空格读入目标字符串- 数值类格式符(如
%d、%lf)默认会跳过前导空白(包括空格、换行符等),但如果前面的格式处理留下了未匹配的字符,会直接干扰数值读取
二、你的代码问题分析
你当前的格式串用%[^,]去读取所有字段,但只有第一个place是字符串类型,中间的year、month、day、magnitude等都是数值类型,这完全是格式符与变量类型不匹配,导致了读取错乱:
- 用字符串格式符读取int/double类型的变量,会把数字字符当作字符串写入数值变量的内存空间,直接破坏内存结构
- 只有第一个字符串字段
place和最后一个用%d匹配的Tsunami能正常读取,中间所有数值字段因为类型不匹配全部读错
三、修正后的代码
根据变量类型替换对应的格式符:
- 整数类型(year、month、day、Tsunami)用
%d - 浮点数类型(magnitude、latitude、longitude)用
%lf
修正后的代码如下:
// 读取部分 fscanf(infile, "%[^,],%d,%d,%d,%lf,%lf,%lf,%d", l->head->place, &l->head->data->year, &l->head->data->month, &l->head->data->day, &l->head->data->magnitude, &l->head->data->latitude, &l->head->data->longitude, &l->head->data->Tsunami); // 打印部分 printf("%s %d %d %d %lf %lf %lf %d", l->head->place, l->head->data->year, l->head->data->month, l->head->data->day, l->head->data->magnitude, l->head->data->latitude, l->head->data->longitude, l->head->data->Tsunami);
四、额外注意事项
- 确保
l->head->place指向的内存空间足够大,能容纳最长的地点字符串,避免缓冲区溢出 - 如果输入的逗号前后有空格,数值格式符会自动跳过,不影响读取;
place字段内的空格也能被%[^,]正确读取(仅以逗号为终止符) - 建议每次调用
fscanf后检查返回值,确认是否成功读取所有8个字段,便于排查输入格式异常:
int read_count = fscanf(infile, "%[^,],%d,%d,%d,%lf,%lf,%lf,%d", ...); if (read_count != 8) { fprintf(stderr, "读取失败,仅成功读取%d个字段\n", read_count); }
内容的提问来源于stack exchange,提问作者maham shaikh
相关产品推荐
相关产品推荐

