CS50中Coleman-Liau可读性指数计算异常求助
问题分析与修复
你的代码输出-2147483648的核心原因有两个:
1. 计算顺序完全错误
你在调用count_letters、count_words、count_sentences这三个计数函数之前就计算了可读性指数相关的L、S和index。此时全局变量letters、words、sentences都是初始值0,执行letters/words会触发整数除以0的未定义行为,最终导致index变成int类型的最小值(-2147483648)。
2. 整数除法导致精度丢失
即便顺序正确,letters/words是整数除法,会直接丢弃小数部分(比如100个字母÷15个单词,整数除法结果是6而非6.666...),后续指数计算必然偏离预期值。
修复后的完整代码
#include <cs50.h> #include <stdio.h> #include <ctype.h> #include <string.h> #include <math.h> int count_letters(string input); int count_words(string input); int count_sentences(string input); int main(void) { // 读取用户输入文本 string input = get_string("Input: "); // 先执行所有计数操作,获取正确的字母、单词、句子数量 int letters = count_letters(input); int words = count_words(input); int sentences = count_sentences(input); // 用浮点运算避免精度丢失:将其中一个整数操作数转为float float L = 100.0 * ((float)letters / words); float S = 100.0 * ((float)sentences / words); int index = round(0.0588 * L - 0.296 * S - 15.8); // 输出结果 printf("Letters: %i\n", letters); printf("Words: %i\n", words); printf("Sentences: %i\n", sentences); printf("Index: %i\n", index); } // 字母计数实现:统计所有大小写字母 int count_letters(string input) { int count = 0; for (int i = 0; input[i] != '\0'; i++) { if (isalpha(input[i])) count++; } return count; } // 单词计数实现:以空格分隔判断单词(兼容首尾无空格的情况) int count_words(string input) { int count = 0; bool in_word = false; for (int i = 0; input[i] != '\0'; i++) { if (isspace(input[i])) { in_word = false; } else if (!in_word) { in_word = true; count++; } } return count; } // 句子计数实现:以. ! ?作为句子结束标记 int count_sentences(string input) { int count = 0; for (int i = 0; input[i] != '\0'; i++) { if (input[i] == '.' || input[i] == '!' || input[i] == '?') { count++; } } return count; }
关键修复点
- 调整执行顺序:先完成计数,再计算指数,确保使用的是实际统计值而非初始0。
- 修正除法运算:通过
(float)letters强制将整数转为浮点型,避免整数除法的精度丢失。 - 移除全局变量:改用局部变量存储计数值,消除全局变量带来的意外赋值风险。
内容的提问来源于stack exchange,提问作者MSK
相关产品推荐
相关产品推荐

