C++使用循环在函数内逐行读取文件统计字母、空格、单词数
问题排查与解决方法
1. 空格/非空格统计错误原因
你原有代码的问题是遍历逻辑错误:循环内比较的是整个字符串的C风格指针line.c_str()和字符串常量" "的内存地址,而非遍历每个位置的单个字符,因此判断条件永远不会按预期触发,才会出现计数全错的情况。
修复后的统计函数示例:
// 统计空格数 int count_space(const string& line) { int space_count = 0; for (int i = 0; i < line.size(); ++i) { if (line[i] == ' ') { // 用单引号包裹单个字符,比较当前位置的字符值 space_count++; } } return space_count; }
非空格统计只要把判断条件的==改为!=即可,两个函数的统计结果天然互补。
2. 单词计数实现方案
通用的单词计数逻辑为:遍历字符时维护「是否处于单词内部」的状态标记,当遇到非单词字符(空格、标点等)时标记离开单词,再次遇到字母等单词起始字符时单词数+1,同时标记进入单词内部。
示例代码:
int count_word(const string& line) { int word_count = 0; bool in_word = false; for (char c : line) { if (isalpha(c)) { // 当前字符是字母,属于单词内容 if (!in_word) { // 刚刚进入单词边界,计数+1 word_count++; in_word = true; } } else { // 遇到非字母字符,标记离开单词 in_word = false; } } return word_count; }
3. 标点符号通用匹配方法
C++标准库的<cctype>头文件提供了ispunct()函数,可直接判断一个字符是否为标点符号,不需要手动枚举所有标点类型。
你提到的单引号匹配问题,用转义字符\'即可实现,判断单引号的写法为if (c == '\'')。
你要的字母统计修正逻辑示例:
#include <cctype> // 需引入该头文件使用字符判断函数 int count_letter(const string& line) { int letter_count = 0; for (char c : line) { // 直接判断是否为字母,自动排除标点、数字、空格等非字母字符 if (isalpha(static_cast<unsigned char>(c))) { letter_count++; } } return letter_count; }
如果要单独判断标点执行扣减逻辑,写法如下:
if (ispunct(static_cast<unsigned char>(line[i]))) { non_space--; }
注意:
ispunct/isalpha等字符判断函数要求输入参数为unsigned char类型或者EOF,直接传入char可能因char是有符号类型出现未定义行为,因此最好做一次强制类型转换。
内容的提问来源于stack exchange,提问作者Malos323
相关产品推荐
相关产品推荐

