2012-09-30 4 views
1

스트림이 포함 된 C++ 과정에 대한 프로그래밍 할당이 있으며 왜 일부 기능이 어떻게 작동하는지 더 잘 이해하려고합니다.입력 스트림에서 읽기

텍스트 뒤에 공백이있는 istringstream에서 입력을 읽습니다. 출력에서 마지막 단어가 반복되는 이유는 무엇입니까?

istringstream is; 
string inputstring = "The cliched statement regarding the big brown dog and foobar or something "; 
string outputstring; 
is.str(inputstring); 
while (is.good()) 
{ 
    is >> outputstring; 
    cout << outputstring << endl; 
} 

그래서, 대신 굿 플래그 루핑, 나는 지금 동안의 조건으로 추출을하고있는 중이 야 :

while (is >> outputstring) 
... 

이 잘 작동하고 마지막 단어를 반복하지 않습니다. 독서를 마쳤을 때 while 회 돌이에서 빠져 나오는 성명서는 무엇입니까? 추출은 동일한 스트림에 대한 참조를 반환하지만 플래그 또는 무언가를 확인합니까?

모든 스트림을 포함 할 수있는 단일 헤더가 있습니까?

+0

서식에 대해 죄송합니다. 나는 한 줄에 하나씩 줄을 긋지 만, 그 줄을 올바르게 파싱하지 않은 것 같습니다. – duffsterlp

답변

1

출력에서 ​​마지막 단어가 반복되는 이유는 무엇입니까?

다음과 같이됩니다. inputstring 끝에 공백이 있기 때문에 마지막 단어를 읽지도 good() 비트가 뒤집히지 않습니다. 프로그램은 마지막 단어 다음에 공백 문자를 찾고 더 많은 단어가 있다고 생각하므로 is.good()은 여전히 ​​true을 반환합니다. is.good()은 프로그램이 문자열의 끝을 지나서 읽으려는 경우에만 false를 반환합니다. 이것은 아직 일어나지 않았다.

그런 다음 루프를 통해 이동 is에서 읽은 다음에, 프로그램은outputstring을 덮어 쓰지 않습니다 , 더 이상의 단어가 없음을 실현하고, 그래서 당신은 인 outputstring에 무슨 전에 한 번 더 쓰기 마지막 단어.

당신은 항상 읽은 후 를 확인해야 ...

+0

다른 사람들의 답변에 대한 의견을 남길만큼 충분한 평판을 얻었습니다. 나는 당신이'. good() '에 대해 옳다고 믿는다. (Dietmar는 내가 그런 실수를하지 않을 것이라고 기대하는 진정한 전문가이다.) 그러나 이것은 실제 대답이 아니다. –

0

을하기 전에 당신이 is에서 읽은 후 is.good()의 결과를 인쇄 해보십시오 및 변경을 확인하려면 다음을 참조하십시오 inputstring의 끝에서 공백 문자를 제거 스트림 수 있기 때문에 좋은 상태에 있지만 뭔가를 읽으려는 시도가 실패 할 수 있습니다. 결국 스트림에서 읽어야 할 내용을 알 수 없습니다. 따라서 마지막 요소 다음에 스트림을 검사하면 여전히 good()입니다. 그렇다면 어떤 시도가 실패하고 good()false이지만 어쨌든 값을 인쇄하십시오.

또한, 당신은하지이 스트림의 마지막에 이르렀을 경우 읽기가 성공 후에도 false로 전환 할 수와 같은 조건으로 .good()을 사용하고자 할 . 예를 들어 숫자가 읽히고 파일 끝에 숫자 뒤에 공백이없는 경우 std::ios_base::eofbit이 설정됩니다.

while (in >> value) { 
    std::cout << "read value='" << value << "'\n"; 
} 

정확하지는 않지만 실제로는 옳은 일을합니다!

+0

사실, 공백이 이전 추출 작업을 끝내고 그 다음 공백이 공백을 건너 뛰고 내용을 찾을 수 없기 때문에 스트림이 공백으로 끝날 때'eofbit'는 마지막으로 성공적으로 읽혀질 때 설정되지 않습니다. 스트림은 실패한 상태로 직접 이동합니다. 마지막 공백 문자가없는 경우 (입력의 마지막 줄에 개행 문자가 없음) 추출 작업은 EOF 조건에 의해 종료되고 'good()'은 성공적으로 읽은 결과 false가됩니다. –

+0

이것이 내가 의도 한 바였습니다. 성공적으로 읽을 수는 있었지만 추출은 파일의 끝에 도달했을 때만 종료 되었기 때문에'std :: ios_base :: eofbit'가 설정됩니다. 공백 문자가없는 값은 그 예입니다. 종료 줄 바꿈없이'std :: getline()'을 사용하는 것도 또 다른 예입니다. 나는 답을 명확히하려고 노력했다. –

+0

@BenVoigt : 그건 의미가 있습니다. 한 번 더 질문, 마지막 추출에서 왜 문자열이 문자열 변수에 빈 문자열을 쓰지 않습니까? 나는 EOF가 빈 문자열 또는 뭔가와 같을 것이라고 기대할 것입니다 ... – duffsterlp

2

읽기가 완료되면 while 루프에서 빠져 나오는이 문장에 대한 설명은 무엇입니까? 추출은 동일한 스트림에 대한 참조를 반환하지만 플래그 또는 무언가를 확인합니까?

추출 연산자가 스트림에 대한 참조를 반환하는 것이 옳습니다. while 루프 (또한 fordo - while 루프 및 if 문)의 제어 조건으로 사용되는 표현식은 bool 유형으로 강제 변환됩니다. explicit으로 계산되므로 ios_base::operator bool()이 호출되어 !this->fail()을 반환합니다. 그리고 이것이 플래그가 체크되는 방식입니다.

+0

도움을 주셔서 감사합니다! 이 계정은 어떻게 EOF를 설명합니까? fail()은 잘못된 비트와 실패 비트를 검사 만하고 eof는 검사하지 않습니다. 또한, bool() 함수는 ios_base 설명서에 문서화되어 있습니까? 나는 어디에도 보이지 않는다 ... – duffsterlp

+0

@ user1590960 : 스트림 끝에있는 결과로 추출에 실패하면'failbit'이 설정됩니다. 즉, 어떤 데이터가 읽혀지고 끝에 도달하면 성공하고'eofbit'이 설정되므로'good()'은 거짓이고'fail()'도 거짓입니다. 그래서 데이터와 루프를 처리하고 다시 시도합니다. 이제 데이터가 읽히지 않고'failbit'이 설정되어 루프를 종료합니다. –

관련 문제