如何用Python以预处理.i文件为输入统计原始C源代码行数?
基于预处理.i文件统计原始C代码行数的Python实现
要从预处理后的.i文件统计原始C代码行数,核心是利用预处理过程中生成的#line指令——这些指令会标记每段代码对应的原始文件名和行号,我们可以通过解析这些指令来跟踪原始代码的位置,避免统计宏展开产生的冗余行。
实现思路
- 解析
#line指令:预处理文件中会包含类似#line 12 "test.c"的指令,其中数字是原始行号,引号内是原始文件名,用正则匹配提取这些信息。 - 跟踪原始代码位置:维护当前对应的原始文件和行号,每遇到一行普通代码(非
#line指令),就记录其对应的原始行位置。 - 去重统计:用集合存储已统计的原始行(格式为
(文件名, 行号)),避免宏展开后同一原始行被多次统计。 - 按文件汇总:最后将统计结果按原始文件名分类输出。
Python代码实现
import re def count_original_c_lines(preprocessed_file_path): # 匹配#line指令的正则:支持带文件名和不带文件名的情况 line_directive_pattern = re.compile(r'^#line\s+(\d+)\s*(?:\"([^\"]+)\")?') counted_original_lines = set() current_original_file = None current_original_line = 0 with open(preprocessed_file_path, 'r', encoding='utf-8') as f: for raw_line in f: stripped_line = raw_line.strip() # 跳过空行(如果需要统计原始空行,删除此判断) if not stripped_line: continue # 处理#line指令,更新当前原始文件和行号 directive_match = line_directive_pattern.match(stripped_line) if directive_match: current_original_line = int(directive_match.group(1)) if directive_match.group(2): current_original_file = directive_match.group(2) continue # 记录有效代码对应的原始行 if current_original_file and current_original_line > 0: counted_original_lines.add((current_original_file, current_original_line)) current_original_line += 1 # 按原始文件汇总行数 line_count_by_file = {} for file, line_num in counted_original_lines: line_count_by_file[file] = line_count_by_file.get(file, 0) + 1 return line_count_by_file # 使用示例 if __name__ == "__main__": result = count_original_c_lines("your_file.i") for original_file, line_count in result.items(): print(f"原始文件 {original_file}: {line_count} 行有效代码")
关键注意事项
- 依赖
#line指令:确保预处理时没有去掉这些指令(比如GCC默认保留,使用-P参数会移除,此时无法用此方法统计)。 - 空行统计选择:代码中默认跳过空行,如果需要统计原始文件中的空行,删除
if not stripped_line: continue这一行即可,但需注意预处理过程中可能生成额外空行。 - 多文件支持:如果原始C代码包含
#include,预处理文件会整合所有头文件内容,本代码会自动按原始文件名分别统计各文件的代码行数。
内容的提问来源于stack exchange,提问作者naomikim
相关产品推荐
相关产品推荐

