sscanf读取特定输入异常:float与double适配问题求助
看起来你遇到的问题根源在于两个关键的格式匹配错误,咱们一步步拆解:
问题1:%i格式符导致的进制解析错误
你用%i来读取月份和日期,但%i会自动识别数字的进制:如果数字以0开头,它会被当作八进制数处理。八进制数的有效范围是0-7,所以当输入里出现09(比如1943-09-01中的月份)时,sscanf无法解析这个无效的八进制数,直接停止后续的解析——这就是为什么你看到month和day都是0,后面的温度、误差值也全错,result只返回2(只成功读取了年份)。
而1972-03-01中的03是有效的八进制数(对应十进制3),所以sscanf能正常解析月份和日期,后续字段也能继续读取,这就是为什么这条输入看起来“正常”(虽然用double读取时温度显示0是另一个小问题)。
问题2:格式字符串与输入格式的细微不匹配
你的格式字符串里写了%i - %i - %i(减号前后带空格),但实际输入是YYYY-MM-DD(减号前后没有空格)。不过sscanf中的空格会匹配任意数量的空白字符(包括0个),所以这个问题在有效八进制数的情况下不会触发,但结合第一个问题时会加重解析失败的情况。
另外,在debug函数中,你用%f打印double类型的变量——虽然printf中%f可以兼容double(因为float会被自动提升为double),但更规范的写法是用%lf,不过这不是导致温度显示为0的主要原因,主要原因还是前面的解析失败导致变量未被正确赋值。
解决方案
把这两个问题修正后,代码就能正常工作了:
- 把日期解析的
%i换成%d:%d强制按照十进制解析数字,不管是否以0开头,这样09会被正确解析为9。 - 修正格式字符串,完全匹配输入格式:去掉减号前后的空格,改成
%d-%d-%d,让格式和输入的YYYY-MM-DD完全对应。 - 规范
printf的格式符:double类型用%lf,float类型用%f,避免混淆。
修正后的代码
#include <stdio.h> #include <stdlib.h> void debug(char* line,int* year, int* month, int* day, double* temp, double* uncertainty, char country[100]){ int result; // 修正格式字符串:用%d代替%i,去掉减号前后的空格 result = sscanf(line, "%d-%d-%d, %lf, %lf, %s", year, month, day, temp, uncertainty, country); // 用%lf打印double类型变量 printf("%d-%d-%d,%lf,%lf,%s\n",*year, *month, *day, *temp, *uncertainty, country); printf("Result:%d\n", result); } void debug_f(char* line, int* year, int* month, int* day, float* temp, float* uncertainty, char country[100]){ int result; // 同样修正格式字符串 result = sscanf(line, "%d-%d-%d, %f, %f, %s", year, month, day, temp, uncertainty, country); // 用%f打印float类型变量 printf("%d-%d-%d,%f,%f,%s\n",*year, *month, *day, *temp, *uncertainty, country); printf("Result:%d\n", result); } int main(){ char* error = "1943-09-01,29.27,0.403,Yemen"; char* working = "1972-03-01,4.787,0.342,Slovakia"; int year1, year2, year3, year4; int month1, month2, month3, month4; int day1, day2, day3, day4; double temp1, temp2; double uncertainty1, uncertainty2; float temp3, temp4; float uncertainty3, uncertainty4; char country1[100], country2[100], country3[100], country4[100]; debug(error, &year1, &month1, &day1, &temp1, &uncertainty1, country1); debug(working, &year2, &month2, &day2, &temp2, &uncertainty2, country2); debug_f(error, &year3, &month3, &day3, &temp3, &uncertainty3, country3); debug_f(working, &year4, &month4, &day4, &temp4, &uncertainty4, country4); }
修正后的输出
1943-9-1,29.270000,0.403000,Yemen Result:6 1972-3-1,4.787000,0.342000,Slovakia Result:6 1943-9-1,29.270000,0.403000,Yemen Result:6 1972-3-1,4.787000,0.342000,Slovakia Result:6
这样所有输入都能被正确解析,result都返回6(表示6个字段全部成功读取)。
内容的提问来源于stack exchange,提问作者chilliefiber
相关产品推荐
相关产品推荐

