C语言水费计算函数运行仅返回0或极大异常数值问题排查
问题原因
- 核心错误是变量类型与格式控制符不匹配:你声明的
water_use是double类型,但fscanf读取时用了%d(仅适配int类型),打印时也用了%d,类型错位导致内存数据解析完全错误,自然会出现0、负0、超大异常值的问题。 - 次要问题是
fscanf的格式串处理逻辑不合理:%c会直接读取包括换行、空格在内的所有字符,你当前的写法很容易把文件里的空行换行符识别为用户类型,导致出现多余的Wrong user type.报错。 - 缺少文件打开成功校验:如果
water_usage.txt不存在或路径错误,fopen会返回空指针,后续读取操作会直接导致程序崩溃。
修正方案
- 把
fscanf和printf里对应water_use的格式符全部改为%lf; - 在
fscanf的%c前加空格,自动跳过所有空白字符,删掉格式串里硬编码的\n\n; - 增加文件打开成功校验逻辑,新增文件关闭操作避免资源泄漏。
修正后完整代码
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <math.h> double water_billcalculation(char user_type, double water_use); int main(void) { FILE* water; water = fopen("water_usage.txt", "r"); // 新增文件打开校验 if (water == NULL) { printf("文件打开失败,请检查路径是否正确\n"); return 1; } char user_type; double water_use; printf("Type\tWater usage\tCost including tax\n"); // 修正格式符,%c前加空格跳过空白符 while (fscanf(water, " %c %lf", &user_type, &water_use) != EOF) { // 修正打印格式符,用水量用%.0lf输出避免显示小数点 printf("%c\t%.0lf\t\t%lf\n", user_type, water_use, water_billcalculation(user_type, water_use)); } fclose(water); return 0; } double water_billcalculation(char user_type, double water_use) { double tc = 0, x; if (user_type == 'G' || user_type == 'g') { x = water_use * .035; tc = x + (x * .087) + 3.75; } else if (user_type == 'B' || user_type == 'b') { x = water_use * .0553; tc = x + (x * .087) + 17.25; } else if (user_type == 'R' || user_type == 'r') { if (water_use <= 400) { x = water_use * .04; tc = x + (x * .087) + 13.5; } else if (water_use > 400 && water_use <= 700) { x = water_use * .062; tc = x + (x * .087) + 13.5; } else { x = water_use * .12; tc = x + (x * .087) + 13.5; } } else { printf("Wrong user type.\n"); } return tc; }
内容的提问来源于stack exchange,提问作者ahsokatano
相关产品推荐
相关产品推荐

