C++词法分词器输出异常换行与MSYS2编译错误问题咨询
问题原因与修复方案
一、异常换行输出的问题
根本原因
你代码里存在三处明确错误共同导致了异常输出:
- 重复读取输入:main函数中while循环条件和循环体内各调用了一次
std::getline,等于每次处理输入前会丢弃一行输入,遇到空输入时就会产生空的分词结果,输出多余换行。 - 变量声明顺序错误:while条件里使用的
input变量在使用前未声明,属于语法错误,不同编译器的兼容处理会引发未定义行为,可能生成空Token。 - 字符串越界访问:
Lexer::advance函数中,当position增加到等于text.length()时,仍然会访问text[position],而C++中std::string的合法下标范围是[0, length()-1],越界访问会读到内存垃圾字符,可能生成无效空Token,输出时就会出现多余空行。
修复代码
先修复Lexer逻辑
// 修改current_char的类型为char,避免不必要的类型转换 class Lexer{ public: std::string text; int position = -1; char current_char; // 这里从std::string改成char void advance(){ this->position += 1; // 增加边界判断,避免越界访问 if (this->position < this->text.size()) { this->current_char = this->text[this->position]; } else { this->current_char = '\0'; // 用'\0'标记输入结束 } } // 其余Lexer逻辑只需要把原来的current_char字符串比较改成字符比较即可,比如: // 原来的this->current_char == "." 改成 this->current_char == '.' };
再修复main函数逻辑
int main(){ std::string input; // 变量提前声明 // 仅在循环条件处读取一次输入,不要重复调用getline while(std::getline(std::cin, input)){ if (input.empty()) continue; // 跳过空行,避免输出多余换行 Lexer mylexer; mylexer.text = input; std::vector<std::string> output = mylexer.make_tokens(); for (int i = 0; i < output.size(); i += 2){ // 用'\n'代替std::endl避免不必要的缓冲区刷新,性能更好 std::cout << output.at(i) << ":" << output.at(i + 1) << '\n'; } // 处理完一行统一输出分隔换行 std::cout << '\n'; } return 0; }
二、MSYS2 g++抛出throw_bad_array_new_lengthv错误的原因
这个错误是C标准库抛出的运行时异常,本质是你的代码中的未定义行为(越界访问、变量未定义使用)导致内存被破坏,触发了数组分配长度检查:当程序尝试分配长度为负数、或者长度超过系统允许最大值的数组时,就会抛出该异常。
Windows下clang-cl默认安全检查等级较低,未定义行为没有触发崩溃,仅输出异常结果;而MSYS2的g默认开启的运行时检查更严格,直接检测到了非法内存操作,所以抛出了错误。修复上述代码问题后,该异常会自动消失。
内容的提问来源于stack exchange,提问作者Redstonerayy
相关产品推荐
相关产品推荐

