專案中需統計 C++ 源文件的:
1. 註釋行數(含純註釋、代碼+註釋混合行)
2. 有效代碼行數(含純代碼、混合行)
3. 代碼註釋公共行數(同一行既有代碼又有註釋)
4. 函數個數(以最外層 `{}` 為標誌)
逐行讀入,逐字符掃描,維護狀態標記:
- `bSyh`:雙引號內(字符串字面量)
- `bXgx`:多行註釋 `/* */` 內
- `bHs`:大括號嵌套層數(-1 表示頂層)
- `bCode`:本行已遇到有效代碼
- `bZs`:本行已遇到註釋
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
string line;
ifstream ifs("Test.cpp");
if (!ifs) { cout << "文件打開失敗" << endl; return 0; }
int bSyh = 0, bXgx = 0, bHs = -1, bCode = 0, bZs = 0;
int nKh = 0, nZs = 0, nDm = 0, nGg = 0, nHs = 0;
while (!ifs.eof()) {
int i = 0;
getline(ifs, line);
bCode = 0; bZs = 0;
if (bXgx) bZs = 1; // 跨行註釋繼續
while (i < line.size() && (line[i]==' '||line[i]=='\t'||line[i]=='\r'||line[i]=='\n')) i++;
if (!bXgx && i == line.size()) { nKh++; continue; } // 空行
while (true) {
// 雙引號處理
if (!bSyh && line[i] == '\"' && (i==0 || line[i-1] != '\\')) { bSyh = 1; i++; continue; }
if (bSyh) {
if (line[i] == '\"' && (i==0 || line[i-1] != '\\')) bSyh = 0;
else if (i == line.size()) { if(bZs)nZs++; if(bCode)nDm++; if(bZs&&bCode)nGg++; break; }
i++; continue;
}
// 單引號跳過
if (line[i] == '\'' && (i==0 || line[i-1] != '\\')) { i += 3; continue; }
// // 註釋
if (!bXgx && line[i] == '/' && i+1 < line.size() && line[i+1] == '/') {
if (bCode) { nZs++; nDm++; nGg++; } else { nZs++; }
break;
}
// /* 開始
if (!bXgx && line[i] == '/' && i+1 < line.size() && line[i+1] == '*') {
i += 2; bXgx = 1; bZs = 1; continue;
}
// 多行註釋中
if (bXgx) {
if (line[i] == '*' && i+1 < line.size() && line[i+1] == '/') { i++; bXgx = 0; }
else if (i == line.size()) { if(bCode){nDm++;nZs++;nGg++;}else{nZs++;} break; }
i++; continue;
}
// 行尾
if (i == line.size()) { if(bZs)nZs++; if(bCode)nDm++; if(bZs&&bCode)nGg++; break; }
// 有效代碼
if (line[i] == '{') bHs++;
else if (line[i] == '}') { if (bHs == 0) nHs++; bHs--; }
i++; bCode = 1;
}
}
cout << "註釋: " << nZs << endl;
cout << "代碼: " << nDm << endl;
cout << "空行: " << nKh << endl;
cout << "公共: " << nGg << endl;
cout << "函數: " << nHs << endl;
return 0;
}
通過狀態機單遍歷實現精確統計,核心在於字符串/字符屏蔽、註釋優先級、跨行狀態維護、行級計數延遲到行尾。代碼可作為代碼分析工具的基礎模塊。