2016-08-17 3 views
0

문제는 다음과 같습니다. 변환해야하는 특정 크기의 청크 문자열을 읽는 사용자 지정 버퍼링 된 입력 스트림을 작성하고 있습니다 (다양한 방법 : 특정 내용을 찾으면 변경된 기호, 전체 청크를 건너 뛰었습니다) . 변환 자체는 atm과 관련이 없습니다. 일반적으로 입력을 이해하는 데 막혀 있기 때문입니다. 다음 (https://stackoverflow.com/a/14086442/3651664에서 기준) 코드입니다 :사용자 정의 버퍼링 된 입력 스트림. End of input

#include <fstream> 
#include <iostream> 
#include <cstring> 

class skipchar_stream_buffer: public std::streambuf 
{ 
private: 
    char* m_buffer; 
    std::streambuf* m_stream_buffer; 
    std::streamsize m_size; 
public: 
    skipchar_stream_buffer(std::streambuf* stream_buffer); 
    virtual ~skipchar_stream_buffer(); 
    virtual std::streambuf::int_type underflow(); 
}; 

skipchar_stream_buffer::skipchar_stream_buffer(std::streambuf* stream_buffer) 
{ 
    m_size = 10; 
    m_buffer = new char[m_size](); 
    m_stream_buffer = stream_buffer; 
} 

skipchar_stream_buffer::~skipchar_stream_buffer() 
{ 
    delete[] m_buffer; 
} 

std::streambuf::int_type skipchar_stream_buffer::underflow() 
{ 
    std::memset(m_buffer, 0, m_size); 

    std::streamsize read = m_stream_buffer->sgetn(m_buffer, m_size); 

    setg(m_buffer, m_buffer, m_buffer + m_size); 

    std::cout << "buffer = '" << m_buffer << "'" << std::endl; 

    if (gptr() == egptr()) 
    return traits_type::eof(); 
    else 
    return traits_type::to_int_type(*gptr()); 
} 

class skipchar_istream: public std::istream 
{ 
public: 
    skipchar_istream(std::istream& stream); 
    virtual ~skipchar_istream(); 
}; 

skipchar_istream::skipchar_istream(std::istream& stream) : 
    std::istream(new skipchar_stream_buffer(stream.rdbuf())) 
{ 

} 

skipchar_istream::~skipchar_istream() 
{ 
    delete rdbuf(); 
} 

int main() 
{ 
    char s[32]; 

    skipchar_istream in(std::cin); 
    in >> s; 
    std::cout << s; 

    return 0; 
} 

는 그리고 질문은 왜 내가 명시 적으로 (예를 들어, EOF를 보내) 입력을 완료해야합니까? 엔터를 눌러서 충분하지 않은 이유는 무엇입니까? 아니면 완전히 잘못하고있는 것입니까? VS2010에서 일하고 있습니다.


업데이트 : 이 코드의 또 다른 문제를 발견 : 공급되는 문자 수는 underflow 방법은 (처음에 한 번만) 자동으로 호출되지 버퍼 사이즈의 배수가 아닌 경우. 왜 그런가요? setg에 포인터 설정이 잘못 되었습니까?

답변

1

Enter 키를 누르면 문자가 I/O 버퍼로 전송됩니다. 그것이 '입력의 끝'을 의미하지는 않습니다. 파일에서 당신은 쉽게 표준 스트림 당신이 입력을 읽는 방법에 많은 유연성을 제공

Dear Mr. Smith,<CR><EOL>I am writing to you this message.<CR><EOL>Kind regards,<CR><EOL>Your Name<EOF> 

같은 것을 할 수 있습니다. 예를 들어

:

istream get() will return you 'D' 
istream operator >> will return "Dear" 
istream getline() will return "Dear Mr. Smith," 
streambuf sgetn (6) will return "Dear M" 

당신은 또한 당신의 요구에 자신의 행동을 조정할 수 있습니다. 따라서 원하는만큼 많이 읽을 수도 있습니다. 코드에서

판독 작업은 다음과 같습니다

의미
std::streamsize read = m_stream_buffer->sgetn(m_buffer, m_size); 

"나 문자 또는 입력의 끝이 발생하면 적은 m_size 제공합니다." 더 자세한 설명은 streambuf의 문서를보십시오.

std :: streambuf는 문자 단위로 작동합니다. 여기에 getline() 또는 연산자 >>가 없습니다. 특정 문자 (예 :)에서 멈추고 싶다면 sgetc()를 사용하여 루프가 필요할 것입니다.

+0

확인. 나는 여전히 잘못된 것을 얻지 못한다. 내가 사용하고있는 입력 스트림은'cin'처럼'istream'에서 파생되었습니다. 그리고'cin'은 줄 바꿈에서 멈 춥니 다. 어떻게해야합니까? – HighPredator

+1

'줄 바꿈에서 멈춤'이 cin에서 구현됩니다. 직접 작성해야합니다 .. – Sergei

+0

감사합니다. – HighPredator

관련 문제