C++逐行读取文件时如何忽略指定部分提取括号内内容
自实现编译器say指令解析修复方案
原代码存在的前置逻辑问题
- 第一次用
while(getline(file, txt))统计行数时,文件读取指针已经移动到文件末尾,第二次循环直接调用getline读不到任何内容,不需要分两次读文件,单次逐行遍历处理即可。 - 原判断say指令的
if(txt.rfind("say"))逻辑错误:rfind返回匹配的下标位置,未匹配时返回string::npos,直接放在if判断中会把非行首出现say的行、甚至不包含say的行误判为say指令。 - 原代码中
txt.ignore("say")、to_string(txt)属于API误用:ignore是输入流的成员方法,不是std::string的方法;to_string用于将数值类型转为字符串,无法对string对象做处理。
say指令内容提取实现逻辑
逐行匹配到合法的say指令后,按以下步骤提取内容:
- 跳过行首的空格、制表符等前导空白,定位到
say关键字的起始位置,校验关键字后是否紧跟左括号( - 定位左括号后第一个双引号
"的位置,再向后查找匹配的第二个闭合双引号 - 截取两个双引号中间的子串,就是需要的输出内容,存入指定变量即可
- 可增加基础语法校验:检查闭合双引号后是否存在右括号
)、行尾分号;,提前抛出语法错误
修正后可运行代码
#include <iostream> #include <string> #include <fstream> #include <cctype> using namespace std; class Life { public: void compile() { ifstream file("index.txt"); // 文件打开失败直接返回 if (!file.is_open()) { cout << "无法打开源码文件index.txt" << endl; return; } string line_content; // 单次逐行遍历即可,不需要提前统计行数 while (getline(file, line_content)) { size_t pos = 0; // 跳过前导空白 while (pos < line_content.size() && isspace(line_content[pos])) { pos++; } // 检查是否匹配say关键字 if (line_content.compare(pos, 3, "say") != 0) { continue; } pos += 3; // 跳过say和括号之间的空白 while (pos < line_content.size() && isspace(line_content[pos])) { pos++; } // 校验左括号 if (pos >= line_content.size() || line_content[pos] != '(') { cout << "say指令语法错误:缺少左括号" << endl; continue; } pos++; // 跳过括号内到第一个引号前的空白 while (pos < line_content.size() && isspace(line_content[pos])) { pos++; } // 校验起始双引号 if (pos >= line_content.size() || line_content[pos] != '"') { cout << "say指令语法错误:缺少字符串起始引号" << endl; continue; } size_t str_start = pos + 1; // 查找闭合双引号 size_t str_end = line_content.find('"', str_start); if (str_end == string::npos) { cout << "say指令语法错误:字符串未闭合" << endl; continue; } // 提取引号内的内容存入变量 string say_content = line_content.substr(str_start, str_end - str_start); // 这里就可以对提取到的say_content做后续编译处理了 cout << "识别到say指令,输出内容为:" << say_content << endl; } file.close(); } }; // 测试用main函数 int main() { Life compiler; compiler.compile(); return 0; }
测试效果
如果index.txt中存在行say("Hello World");,程序运行后会输出:
识别到say指令,输出内容为:Hello World
内容的提问来源于stack exchange,提问作者AyE
相关产品推荐
相关产品推荐

