我一直在解析文件和使用 seekg() 时遇到问题。每当在文件中达到某个字符时,我想循环直到满足条件。循环在第一次迭代时工作正常,但是当它循环返回时,文件似乎跳过了一个字符并导致循环无法按预期运行。
具体来说,如果循环全部包含在文件的一行中,则循环可以正常工作,但当文件中的循环中至少有一个换行符时,循环会失败。
我应该提到我正在 Windows 上处理这个问题,我觉得问题出在 Windows 如何以\r\n
.
使用seekg(-2, std::ios::cur)
after looping 解决了当开始循环条件后紧跟换行符时的问题,但不适用于同一行中包含的循环。
代码的结构是让解释器类保存文件指针和相关变量,例如当前行和列。此类还具有如下定义的功能映射:
// Define function type for command map
typedef void (Interpreter::*function)(void);
// Map for all the commands
std::map<char, function> command_map = {
{'+', increment_cell},
{'-', decrement_cell},
{'>', increment_ptr},
{'<', decrement_ptr},
{'.', output},
{',', input},
{'[', begin_loop},
{']', end_loop},
{' ', next_col},
{'\n', next_line}
};
它遍历每个字符,在以下函数中确定它是否具有功能:
// Iterating through the file
void Interpreter::run() {
char current_char;
if(!this->file.eof() && this->file.good()) {
while(this->file.get(current_char)) {
// Make sure character is functional command (ie not a comment)
if(this->command_map.find(current_char) != this->command_map.end()) {
// Print the current command if in debug mode
if(this->debug_mode && current_char != ' ' && current_char != '\n') {
std::cout << this->filename << ":" << this->line << ":"
<< this->column << ": " << current_char << std::endl;
}
// Execute the command
(this->*(command_map[current_char]))();
}
// If it is not a functional command, it is a comment. The rest of the line is ignored
else{
std::string temp_line = "";
std::getline(file, temp_line);
this->line++;
this->column = 0;
}
this->temp_pos = file.tellg();
this->column++;
}
}
else {
std::cout << "Unable to find file " << this->filename << "." << std::endl;
exit(1);
}
file.close();
}
循环的开始(由 '[' 字符表示)将开始循环位置设置为this->temp_pos
:
void Interpreter::begin_loop() {
this->loop_begin_pointer = this->temp_pos;
this->loop_begin_line = this->line;
this->loop_begin_col = this->column;
this->run();
}
当到达循环结束时(由 ']' 字符表示),如果不满足结束循环的条件,则将文件光标位置设置回循环的开头:
void Interpreter::end_loop() {
// If the cell's value is 0, we can end the loop
if(this->char_array[this->char_ptr] == 0) {
this->loop_begin_pointer = -1;
}
// Otherwise, go back to the beginning of the loop
if(this->loop_begin_pointer > -1){
this->file.seekg(this->loop_begin_pointer, std::ios::beg);
this->line = this->loop_begin_line;
this->column = this->loop_begin_col;
}
}
我能够输入调试信息,并且可以显示堆栈跟踪以进一步明确问题。
单行循环的堆栈跟踪 ( ++[->+<]
):
+ + [ - > + < ] [ - > + < ] done.
这按预期工作。
多行循环:
++[
-
>
+<]
堆栈跟踪:
+ + [ - > + < ] > + < ] <- when it looped back, it "skipped" '[' and '-' characters.
由于永远不会满足结束条件,因此永远循环(即第一个单元格的值永远不会为 0,因为它永远不会递减)。
奇怪的是,以下工作:
++[
-
>+<]
它遵循与第一个示例相同的堆栈跟踪。这个工作和最后一个例子不工作是什么让我很难解决这个问题。
如果需要有关程序应该如何工作或其输出的更多信息,请告诉我。抱歉,这篇文章太长了,我只想尽可能清楚。
编辑 1:该类的文件对象为std::ifstream file;
. 在构造函数中,它以 开头
this->file.open(filename)
,其中filename
作为参数传入。