2016-08-17 6 views
0

問題は次のとおりです。変換する必要がある特定のサイズのチャンクで文字列を読み込むカスタムのバッファリングされた入力ストリームを作成しています(変更されたシンボル、特定のコンテンツが見つかるとスキップされた全体のチャンクなど) 。私は一般的に入力を理解しているので、変換そのものはatmとは関係ありません。ここで(https://stackoverflow.com/a/14086442/3651664からベース)コードです:カスタムバッファリングされた入力ストリーム。入力の末尾

#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

'newlineで停止する'はcinで実装されています。あなた自身でそれを書いてください。 – Sergei

+0

、ありがとう、ありがとう。 – HighPredator

関連する問題