统计C++源代码的有效代码行数,需要排除空行和各类注释内容,核心思路是逐行读取文件内容,对每一行进行状态判断,过滤无效内容后计数。

核心判断逻辑
要实现准确统计,需要先明确需要排除的内容类型和判断规则:
- 空行:行内仅包含空格、制表符等空白字符,或者行内容为空。
- 注释行:分为单行注释(以//开头)和多行注释(以/*开头,以*/结尾)两种情况,需要注意多行注释可能跨越多行。
- 有效代码行:既不是空行,也不属于注释内容的行,即使一行内同时包含代码和注释,只要存在有效代码部分,也计入统计。
实现方案说明
我们可以通过维护一个多行注释的状态标记,逐行处理文件内容:
- 初始化一个布尔变量
in_multi_comment为false,标记当前是否处于多行注释中。 - 逐行读取目标文件,先去除行首尾的空白字符,判断是否为空行。
- 如果处于多行注释中,检查当前行是否包含*/,若包含则更新状态,该行不计入有效行。
- 如果不在多行注释中,检查行内是否包含//或/*,处理单行注释和多行注释的起始逻辑,同时判断该行是否存在有效代码内容。
完整示例代码
以下是可直接编译运行的C++统计程序:
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;
// 去除字符串首尾的空白字符
string trim(const string &str) {
size_t first = 0;
while (first < str.size() && isspace(static_cast<unsigned char>(str[first]))) {
++first;
}
size_t last = str.size();
while (last > first && isspace(static_cast<unsigned char>(str[last - 1]))) {
--last;
}
return str.substr(first, last - first);
}
// 统计单个文件的有效代码行数
int count_valid_lines(const string &file_path) {
ifstream file(file_path);
if (!file.is_open()) {
cerr << "无法打开文件: " << file_path << endl;
return -1;
}
int valid_count = 0;
bool in_multi_comment = false;
string line;
while (getline(file, line)) {
string trimmed_line = trim(line);
// 判断是否为空行
if (trimmed_line.empty()) {
continue;
}
// 处理多行注释状态
if (in_multi_comment) {
// 检查当前行是否结束多行注释
size_t end_pos = trimmed_line.find("*/");
if (end_pos != string::npos) {
in_multi_comment = false;
// 检查*/之后是否还有有效代码
string after_comment = trimmed_line.substr(end_pos + 2);
after_comment = trim(after_comment);
if (!after_comment.empty() && after_comment.find("//") != 0) {
valid_count++;
}
}
continue;
}
// 检查是否为单行注释
size_t single_comment_pos = trimmed_line.find("//");
size_t multi_comment_start = trimmed_line.find("/*");
size_t multi_comment_end = trimmed_line.find("*/");
// 处理多行注释起始
if (multi_comment_start != string::npos) {
// 多行注释在同一行结束
if (multi_comment_end != string::npos && multi_comment_end > multi_comment_start) {
// 检查注释前后的代码
string before_comment = trimmed_line.substr(0, multi_comment_start);
before_comment = trim(before_comment);
string after_comment = trimmed_line.substr(multi_comment_end + 2);
after_comment = trim(after_comment);
if (!before_comment.empty() || (!after_comment.empty() && after_comment.find("//") != 0)) {
valid_count++;
}
} else {
// 多行注释跨多行
in_multi_comment = true;
// 检查/*之前是否有有效代码
string before_comment = trimmed_line.substr(0, multi_comment_start);
before_comment = trim(before_comment);
if (!before_comment.empty()) {
valid_count++;
}
}
continue;
}
// 处理单行注释
if (single_comment_pos != string::npos) {
// 检查//之前是否有有效代码
string before_comment = trimmed_line.substr(0, single_comment_pos);
before_comment = trim(before_comment);
if (!before_comment.empty()) {
valid_count++;
}
continue;
}
// 普通有效代码行
valid_count++;
}
file.close();
return valid_count;
}
int main() {
string file_path;
cout << "请输入要统计的C++源代码文件路径: ";
cin >> file_path;
int result = count_valid_lines(file_path);
if (result != -1) {
cout << "该文件的有效代码行数为: " << result << endl;
}
return 0;
}
使用说明
编译运行程序后,输入目标C++源代码文件的绝对路径或相对路径,程序会输出过滤空行和注释后的有效代码行数。该实现可以处理大部分常见的C++注释场景,包括单行注释、多行注释、同一行内的代码加注释等情况。