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

예 : fname의 길이 < = 1이면

validate <file name> 
display <file name> 
exit 
+1

컴파일러 오류가 아닙니다 .__입니다. __runtime error__입니다. 태그를 수정하십시오. – Hindol

+3

그래서 디버깅을 시작하십시오. 코드에 print 문을 많이 추가하고 실패한 영역을 좁 힙니다. 또는 디버거를 사용하십시오. –

+0

아마도 사용자 입력이 너무 작 으면 입력 변수 fname ...을 처음으로 온 전성 체크하십시오. 문자열 이름 = fname.substr (1, fname.length() - 2); – jaybny

답변

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

예외의 종류를 던질 것이다. 나는 이것이 사실이라고 확신한다. 가장 단순한 (최선은 아님) 해결책은 그러한 행을 건너 뛸 수 있습니다.

관련 문제