必须用std::getline或std::istreambuf_iterator逐行/逐字符读取,避免operator>>跳过换行导致代码压成一行;需跳过utf-8 bom、用状态机识别语法结构、全行html转义后再高亮、按c++标准版本动态启用关键字。

用 std::ifstream 读取 C++ 源文件时,别跳过换行和空格
直接用 operator>> 读字符串会跳过所有空白符(包括换行),导致整段代码被压成一行,后续词法分析完全失效。必须用 std::getline 或 std::istreambuf_iterator 逐行/逐字符读取。
-
std::getline(in, line)最稳妥:保留每行原始结构,方便后续按行做注释检测、缩进计算 - 若需逐字符处理(比如状态机式高亮),用
std::istreambuf_iterator<char>(in)</char>配合std::string构造,比in.get()循环快且不跳空白 - 注意文件编码:Windows 上常见 UTF-8 with BOM,开头三个字节
必须跳过,否则第一个 token 会错位
识别关键字、字符串、注释不能靠 std::string::find 简单匹配
C++ 语法有嵌套和转义约束,正则或子串搜索极易误判。比如 std::string 中的 "class" 不是关键字;// class 后面的 class 也不该高亮。
- 必须用状态机驱动:维护当前是否在字符串
"..."、字符常量'''、行注释//、块注释/*...*/内部 - 关键字判断只在「自由态」(不在任何字面量或注释中)下进行,且需完整单词匹配(前后为非标识符字符,如空格、
{、;) - 字符串内反斜杠转义要解析:遇到
"或\时不结束字符串,避免提前退出高亮状态
简单高亮输出 HTML 时,、<code>>、& 必须转义
源码里有 vector<int></int> 或 a && b,直接写进 HTML 会导致标签被浏览器解析,轻则显示异常,重则 XSS(如果输出未隔离)。
- 对每一行内容,在插入
<span class="keyword"></span>前,先全局替换:&→&,→ <code><,>→> - 不要只对关键字部分转义——整个源码行都要先净化,再分段包裹
<span></span>,否则cout 中的 <code> 可能被当 HTML 标签吃掉 - 如果目标是终端输出(非 HTML),则改用 ANSI 转义序列,但要注意 Windows 默认控制台需调用
SetConsoleOutputCP(CP_UTF8)和SetConsoleMode(... ENABLE_VIRTUAL_TERMINAL_PROCESSING)
关键字列表不能硬编码全部 C++20 关键字,得按标准版本切分
比如 concept、requires 在 C++20 才是关键字,在 C++17 中可能是合法标识符。工具若默认启用全部,会在老项目里误标。
- 建议用编译器内置宏做条件:检查
__cplusplus值,202002L表示 C++20,201703L表示 C++17 - 把关键字分为基础集(
if、for、class)和扩展集(consteval、co_await),后者仅当版本达标时激活 - 注意
export这种“有条件关键字”:模块模式下才是关键字,否则是普通标识符——简单高亮工具可暂不支持此上下文敏感逻辑,但文档里得写明限制
R"xxx(...)"xxx 的识别:它不处理内部任何转义,且结束标记必须与起始标记完全一致。没处理这个,遇到 R"(a
b)" 就会错误地在
处截断。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











