0

我的程序出现这个错误,我不明白为什么。代码本质上必须检查存储在声明为全局变量的集合中的标记。如果它是有效标签,则将其存储在堆栈中,否则返回错误消息。然后它检查(如果它是一个有效的标签)结束标签是否有序。这就是 is_well_formed 方法的全部内容。对于 print_well_formed_file 方法,它本质上检查给定文件是否格式正确,如果它会显示该文件。:

terminate called after throwing an instance of 'std::out_of_range'
what():  basic_string::substr

我能做些什么来解决这个错误?这是代码的一部分:

bool is_well_formed(ifstream& ifs, string& error_msg) {
    // your code goes here
    string fname, line;
    Token tok;
    Lexer lexer;
    tags.insert("blue");
    tags.insert("red");
    tags.insert("cyan");
    tags.insert("white");
    tags.insert("yellow");
    tags.insert("magenta");
    tags.insert("dim");
    tags.insert("underline");
    tags.insert("bold");
    while (getline(cin, fname)) {
        // tries to open the file whose name is in string fname
        string name = fname.substr(1, fname.length() - 2);
        cout << "Name" + name;
        ifs.open(name.c_str());
        if (ifs.fail()) {
            cerr << "ERROR: Failed to open file " << fname << endl;
            ifs.clear();
        } else {
            while (getline(ifs, line)) {
                lexer.set_input(line);
                while (lexer.has_more_token()) {
                    tok = lexer.next_token();
                    string tmpTok = tok.value;
                    switch (tok.type) {
                    case TAG:
                        // If it has /, remove / from tmpTok
                        if (tok.value[0] == '/') {
                            tmpTok = tmpTok.substr(1, tmpTok.length() - 1);
                        }
                        if (tags.find(tmpTok) == tags.end()) {
                            // Check whether the encountered tag is valid
                            error_return("Tag " + tmpTok + " is invalid!");
                        } else {
                            // Valid Tag encountered
                            stack < string > tagstack;
                            tagstack.push(tmpTok);
                            // Check if the tags are formed properly
                            if (tok.value[0] == '/') {
                                // Remove / from tmpTok
                                string closingTag = tmpTok;
                                string openingTag = tagstack.top();
                                tagstack.pop();
                                if (closingTag.compare(openingTag) != 0) {
                                    error_return(
                                            closingTag + "doesn't match"
                                                    + openingTag);
                                } //else 
                                //  return true; // if the file is well formed
                            }
                        }
                        break;
                    case IDENT:
                        cout << "IDENT: " << tok.value << endl;
                        break;
                    case ERRTOK:
                        error_return("Syntax error on this line\n");
                        //cout << "Syntax error on this line\n";
                        break;
                    case ENDTOK:
                        break;
                    }
                }
            }
        }
    }
    return true; // if the file is well-formed
}

void print_well_formed_file(ifstream& ifs) {
    //Check if file is well formed.
    string line;
    Lexer command;
    if (is_well_formed(ifs, line)) { //if well formed display
        command.set_input(line);
        display(command);
    }

}
void display(Lexer cmd_lexer) {
    string file_name;

    if (!parse_input(cmd_lexer, file_name)) {
        error_return("Syntax error: display <filename>");
        return;
    }

    ifstream ifs(file_name.c_str());
    string error_msg;
    if (ifs) {
        if (!is_well_formed(ifs, error_msg)) {
            error_return(error_msg);
        } else {
            ifs.clear(); // clear EOF flag
            ifs.seekg(0, ios::beg); // go back to the very beginning
            print_well_formed_file(ifs);
        }
    } else {
        error_return("Can't open " + file_name + " for reading");
    }
    ifs.close();
}

用户输入示例:

validate <file name>
display <file name>
exit
4

1 回答 1

1
string name = fname.substr(1, fname.length() - 2);

fname如果的长度 <= 1将抛出这种异常。我敢打赌,情况就是这样。最简单(不是最好)的解决方案是跳过这些行。

于 2012-09-26T06:04:30.243 回答