使用sscanf解析CSV文件出现垃圾值,求问题原因及解决
用sscanf解析CSV出现垃圾值的原因分析
问题重现
尝试用sscanf解析CSV文件,编写了checkString函数检测行首引号,但运行后输出出现00doA这类垃圾值,相关代码、CSV内容及异常输出如下:
检测函数代码
int checkString(const char *str) { if (str[0] == '"') { return 1; } return 0; }
主函数代码
int main() { char inputLine[100]; //input line Node *pList = NULL; //initialize linked list FILE *inputStream = fopen("../musicPlayList.csv", "r"); Record testArr[100]; Record inputRecord; Duration inputDuration; int inputTimesPlayed = 0; int inputRating = 0; char artistToken[20]; char albumTitleToken[20]; char songTitleToken[20]; char genreToken[20]; char durationToken[20]; char timesPlayedToken[20]; char ratingToken[20]; if (inputStream != NULL) { while (fgets(inputLine, sizeof(inputLine), inputStream) != NULL) { if (checkString(inputLine)) { sscanf(inputLine, "\"%[^\"]\" %s %s %s %s %s %s", artistToken, albumTitleToken, songTitleToken, genreToken, durationToken, timesPlayedToken, ratingToken); } else { sscanf(inputLine, "%s %s %s %s %s %s %s", artistToken, albumTitleToken, songTitleToken, genreToken, durationToken, timesPlayedToken, ratingToken); } printf("%s %s %s %s %s %s %s\n", artistToken, albumTitleToken, songTitleToken, genreToken, durationToken, timesPlayedToken, ratingToken); } } return 0; }
CSV文件内容
"Swift, Taylor",1989,Shake it Off,Pop,3:35,12,3 Drake,NOTHING WAS THE SAME,Own it,Rap,3:23,3,3 Drake,YOU WELCOME,The Motto,Rap,4:13,7,4 "Perri, Christina",HEAD OF HEART,Trust,Pop,2:35,3,5 "Bieber, Justin",PURPOSE,No Sense,Pop,4:12,6,1 Eminem,SHADYXV,Vegas,Rap,3:37,8,3 Adele,25,Remedy,Pop,4:11,24,4 "Swift, Taylor",RED,Stay Stay Stay,Pop,4:42,5,1 "Brooks, Garth",FRESH HORSES,The Old Stuff,Country,2:57,11,2
异常输出
Swift, Taylor ,1989 , Shake it Off, Pop, 3:35,12,3 00doA Drake, NOTHING WAS THE SAME, Own it, Rap, 3:23,3, 3 Drake, YOU WELCOME, The Motto, Rap, 4:13,7,4 SAME, Own it, Rap, 3:23,3,3 Perri, Christina ,HEAD ,3,5 HEART, Trust, Pop,2:35,3,5 it, Rap, 3:23,3,3 Bieber, Justin ,PURPOSE, No Sense, Pop, 4:12,6,1 HEART, Trust, Pop, 2:35Sense, Pop, 4:12,6,1 it, Rap, 3:23, 3, 3 Eminem, SHADYXV, Vegas, Rap, 3:37,8,3 , PURPOSE, No Sense, Pop, 4:12,6,1 HEART, Trust, Pop, 2:35Sense, Pop, 4:12,6,1 it, Rap, 3:23,3, 3 Adele, 25, Remedy, Pop, 4:11, 24,4 , PURPOSE, No Sense, Pop, 4:12,6,1 HEART, Trust, Pop, 2:35Sense, Pop, 4:12,6,1 it, Rap, 3:23,3 , 3 Swift, Taylor ,RED, Stay Stay Stay, Pop, 4:42,5,1 it, Rap, 3:23,3, 3 Brooks, Garth ,FRESH HORSES, The 1,2 Stuff, Country,2:57, 11, 2 Process finished with exit code 0
问题原因
分隔符匹配错误:CSV的字段分隔符是逗号,但你的
sscanf格式字符串用空格作为分隔依据。比如第一行解析完引号内容后,会把,1989当成一个完整字段读入,后续所有字段全部错位,未被覆盖的内存旧数据或随机值就会被输出。字符数组未初始化:定义的
artistToken等字符数组没有初始化,第一次循环时如果sscanf没有完全覆盖数组内容,剩余位置会保留内存中的随机垃圾值(比如00doA)。带空格字段解析失败:像
Shake it Off、NOTHING WAS THE SAME这类包含空格的字段,%s格式符只会读取到第一个空格就停止,导致字段被截断,后续解析彻底混乱,旧数据残留输出。引号后逗号未处理:在带引号的行中,格式字符串
"\"%[^\"]\" %s..."解析完引号内容后,直接用空格匹配,但实际引号后是逗号(比如"Swift, Taylor",1989),逗号不是空格,导致后续字段全部错位,残留数据被打印。
内容的提问来源于stack exchange,提问作者sangregoriokimpo
相关产品推荐
相关产品推荐

