2010-06-24 2 views
0

내 프로그램에서 stdout을 'console.txt'파일로 인쇄하도록 리디렉션했습니다. 함수는 다음과 같이 그 파일에 기록 : readLogFile가 호출 될 때ifstream에서 읽을 때 쓸데없는 빈 행

void Console::readLogFile() 
    { 
     ifstream log("console.txt", ifstream::in); 
     if(!log.is_open()) 
     { 
      cerr << "ERROR: console.txt not found!" << endl; 
      return; 
     } 

     // read new input into the stack 
     char str[256]; 
     while(!log.eof()) 
     { 
      log.getline(str, 256); 
      cerr << "str: " << str << endl; 
      stk.push(static_cast<string>(str)); 
      // stk is a std::stack<std::string> member of the class this function 
      // belongs to. 
     } 
     cerr << endl; 

     /* Do some stuff with str and stk here */ 

     log.close(); 
     clearLogFile(); 
    } 

    void Console::clearLogFile() 
    { 
     FILE* log; 
     log = fopen("console.txt", "w"); 
     fclose(log); 
    } 

가 종종 console.txt이 비어 :이처럼 보이는 해당 파일에서 읽는 기능이

void printToConsole(const std::string& text, const TCODColor& fc, const TCODColor& bc) 
    { 
     // write the string 
     cout << text << "@"; 

     // write the two color values 
     cout << static_cast<int>(fc.r) << " " 
      << static_cast<int>(fc.g) << " " 
      << static_cast<int>(fc.b) << " " 
      << static_cast<int>(bc.r) << " " 
      << static_cast<int>(bc.g) << " " 
      << static_cast<int>(bc.b) << " " << endl; 
    } 

. 나는 그 경우에 while(!log.eof()) 루프가 결코 실행되지 않을 것이라고 기대하지만, 그렇습니다. 파일에는 적어도 하나 이상의 불필요한 공백 행이 있고 때로는 두 개가 있으며 파일에서 입력을 읽을 때 입력 행은 두 개의 공백 행 사이에 끼워집니다. 이 함수를 몇 번 호출하면 while(!log.eof()) 루프가 파일에서 빈 행을 가져 오는 무한 루프로 이동합니다. 프로그램의 일반적인 실행은 다음과 같습니다.

str: 

str: Player [email protected] 191 191 0 0 0 
str: 

str: 
str: Player [email protected] 191 191 0 0 0 
str: 

str: // there should be a 'Player moved.' line in here 
str: 

str: // here as well 
str: 

str: // also here 
str: 

str: 
str: Player [email protected] 191 191 0 0 0 
str: 

str: 
str: 
str: 
str: 
str: 
str: 
(onto infinite loop) 

내가 여기서 잘못하고있는 것을 누구든지 볼 수 있습니까?

편집 : Amardeep이 제안했듯이 while(!log.eof()) 루프를 do{...}while(!log.fail); 루프로 변경했습니다. 이렇게하면 무한 루프 문제가 해결되지만 관계없는 행은 해결되지 않습니다.

str: 

str: 

str: 

str: 
(etc.) 

답변

1

EOF() 당신이 시도 될 때까지 상태가 설정되지 않은 :이 프로그램은 한 번 무한 루프에 들어간 경우를 제외하고, 지금 이런 식으로 입력을 읽어야 빈 줄만을 읽고,하지, 이전과 동작 독서. read 루프를 변경하여 getline()을 실행 한 다음 eof()에 의존하는 대신 fail() 상태를 확인해야합니다. eof()는 파일을 읽는 동안 잘못 될 수있는 범위를 다루지 않습니다.

+0

while (! log.ofail()); '루프로 while (! log.eof())를 변경하여 무한 루프 문제를 해결했지만 그것은 여전히 ​​관계없는 빈 줄에서 읽고 있습니다. – Max

+0

읽은 후'push '를 호출하기 전에'fail'을 확인해야합니다. 루프의 중간에서 추한 if 문을 사용하지 않으려면 코드를'log '로 변경하면됩니다.log.getline (str, 256); getline (str, 256); while (! log.fail()) {cerr << "str :"<< str << endl; stk.push (static_cast (str) ;}' – Brian

+0

거의 제 문제가 수정되었습니다. 읽기 루프는 이제 괜찮습니다. 문제는 내 'clearLogFile' 함수에 있습니다. 주석으로 처리하면 예상대로 작동합니다 (파일이 지워지지 않았으므로 오래된 데이터를 읽지 만). 실제 입력의 각 행 앞에 관계없는 빈 줄이 있고 잠시 후 입력에서 모두 함께 읽는 것을 멈 춥니 다 (분명히'fail'에 대한 체크는 박쥐 오른쪽에서 true를 반환합니다). – Max

1

파일을 읽기위한 표준 안티 패턴.

while(!log.eof()) 
    { 
     log.getline(str, 256); 
     cerr << "str: " << str << endl; 
     stk.push(static_cast<string>(str)); 
     // stk is a std::stack<std::string> member of the class this function 
     // belongs to. 
    } 

이 시도 :

의 getline() 메소드는 스트림에 대한 참조를 반환하기 때문에이 작동
while(log.getline(str, 256)) 
    { 
     cerr << "str: " << str << endl; 
     stk.push(string(str)); 
    } 

.

부울 컨텍스트에서 스트림을 사용할 때 bool로 변환됩니다 (실제로는 초보자에게는 적합하지 않지만 초보자에게는 좋음). 스트림이 읽기 후에도 상태가 양호하면 (즉, 읽기가 작동 한 경우) 스트림은 true로 변환됩니다. 스트림의 상태가 나쁜 경우 (즉, 읽기에 실패한 경우) 스트림은 false로 변환됩니다. 따라서 읽기가 작동하면 루프가 입력됩니다. 읽기가 실패한 경우 (아마도 EOL이 읽혀지기 때문에) 루프는 입력되지 않습니다.

읽기 (getline()) 후에 eof()를 테스트하지 않았기 때문에 버전이 실패했습니다. 왜냐하면 마지막 좋은 읽기는 EOF까지 모든 문자를 읽기 때문입니다. 그러나 이것은 eof 플래그가 설정되지 않았 음을 의미합니다. 실제로 EOF를 읽으려고 할 때까지는되지 않습니다 (이것은 EOF 플래그가 설정되어있는 마지막 읽기 이후에 다른 모든 문자를 읽은 경우에만 발생합니다).

추신. 스트림에서 문자열로 읽는 자유 함수가 있습니다.

std::string line; 
std::getline(log, line); 
+0

좋아, 고마워. 이것은 내 문제를 해결하지 못했지만 내 코드를 개선했습니다. 앞으로도 계속 그 점을 명심 해 두겠습니다. – Max

관련 문제