自定义缓冲输入流.输入结束



问题如下:我正在编写一个自定义缓冲输入流,该输入流读取应该转换的特定大小块中的字符串(各种方式:更改符号,如果找到特定内容则跳过整个块等)。变换本身是无关紧要的,因为我被困在理解一般的输入上。下面是代码(基于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)?为什么按回车键不够?还是我做的完全错了?

更新:发现这段代码的另一个问题:如果提供的字符计数不是缓冲区大小的倍数,则不会自动调用underflow方法(最初只调用一次)。为什么呢?

是smth错误的指针设置在setg ?

按回车键将字符发送到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的文档以获得更好的解释。http://www.cplusplus.com/reference/streambuf/streambuf

std::streambuf以字符为基础工作。这里没有getline()或操作符>>。如果你想停在一个特定的字符(例如)上,你可能需要使用sgetc()进行循环。

最新更新