简体   繁体   中英

C++ error in program

I'm getting this error on my program and I don't understand why. The code essentially has to check for tags stored in a set which is declared as a global variable. If it's a valid tag it stores it in the stack if not returns a error message. Then it checks (if its a valid tag)if the closing tags are in order. This is all for the is_well_formed method. For the print_well_formed_file method it essentially checks if the given file is well formed if it is it'll display the file.:

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

What can I do to fix this error ? This is part of the code:

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();
}

Example of user input:

validate <file name>
display <file name>
exit
string name = fname.substr(1, fname.length() - 2);

Will throw this kind of an exception if fname 's length is <= 1 . I bet, this is the case. The simplest(not the best) solution is to skip such lines.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM