2012-09-26 41 views
0

我在程序中收到這個錯誤,我不明白爲什麼。代碼本質上必須檢查存儲在聲明爲全局變量的集合中的標記。如果它是一個有效的標籤,它將它存儲在堆棧中,如果沒有返回錯誤消息。然後它檢查(如果其有效標籤)結束標籤是否有序。這是所有的is_well_formed方法。對於print_well_formed_file方法它本質檢查,如果給定的文件是格式良好的,如果它是,它會顯示文件:程序中出現C++錯誤

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 
+1

它是__not一個編譯器error__。這是一個__runtime錯誤_。修復你的標籤。 – Hindol

+3

於是開始調試。爲您的代碼添加大量打印語句,縮小它失敗的範圍。或者使用調試器。 –

+0

也許第一個理智 - 檢查你的輸入變量fname ...如果用戶輸入太小,將會失敗。 string name = fname.substr(1,fname.length() - 2); – jaybny

回答

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

將引發這種異常的如果fname的長度是< = 1。我敢打賭,情況就是這樣。最簡單的(不是最好的)解決方案是跳過這些行。