跟踪输入流中的信息 [英] Tracking information in input stream

查看:60
本文介绍了跟踪输入流中的信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个流或streambuf来跟踪已读取的

行的数量以及类似的内容(例如,当我

时得到一条错误消息,我可以向流询问行号并将错误消息放入

。我尝试创建一个streambuf类,其中包含另一个

的另一个实例streambuf(通过参数化继承)和

会将呼叫从一个传送到另一个,跟踪数据,因为它是读取b
但是我无法获得找到数据所在的钩子

传递给调用的应用程序。


这个问题已经解决了吗?有没有找到的地方< br $>
现成的解决方案?


无论如何,感谢阅读。


Adam H. Peterson

解决方案

" Adam H. Peterson"< ah ** @ email.byu.edu>写在留言中

news:cp *********** @ acs2.byu.edu ... 我想创建一个流或streambuf来跟踪已经读过的行的数量


你不需要创建您自己的流或

流缓冲区类型来执行此操作。


只需在阅读时计算新闻热线字符。

和东西就像那个



像这样的东西是一个模糊的短语,我甚至不会试图解决它。

(所以,例如,当我收到错误信息时,我可以向流询问行号并将其放入错误消息中。


输出您在

时递增的计数器的值遇到换行符。

我试图创建一个streambuf类,其中包含另一个streambuf的实例(通过参数化继承),并且
会将调用从一个传递到另一个,跟踪数据,因为它已读取,但我无法找到一个钩子,找到数据传递到调用应用程序的位置。


我认为你制造的东西比必要的要复杂得多。

这个问题是否已经解决了?有没有可以寻找现成解决方案的地方?




只需循环执行你的i / o(无论如何都要这样做)。

你究竟如何计算换行符取决于关于你用于你的i / o的函数

。例如。如果你使用cin.get(),请检查它'

''\ n''的返回值。如果您使用例如''std :: getline'',当

它返回时,你知道你遇到了换行符,或者说是
EOF(或发生错误)。你可以用以下方法理清发生的事情

''eof()''和''失败()''


-Mike


Mike Wahler写道:

" Adam H. Peterson" <啊** @ email.byu.edu>在消息中写道
新闻:cp *********** @ acs2.byu.edu ...

我想制作一个流或者streambuf跟踪已读取的行的数量

您不需要创建自己的流或
流缓冲区类型来执行此操作。

只是在你阅读时计算新闻热线字符。




但这对我来说并不是很有用。如果我有以下代码:


void f(istream& i){

Object o;

i>> o;

}


我真的不想在Object'的流提取中徘徊

运算符,而我可能无法做到。拥有不透明的I / O
例程是很常见的,这些例程可以读取和写入各种类型的对象或数据结构。通常我无法对它们进行检测,即使我可以,它通常会与原始代码相比产生相当混乱的代码。

所以我不喜欢我总是可以选择跟踪我读的东西

---也就是说,除非我能让流为我做这件事。

我试图创建一个streambuf类,其中包含另一个streambuf的实例(通过参数化继承),并且
会将调用从一个调用到另一个,跟踪数据因为它已被阅读,但我无法找到一个钩子,找到数据传递到调用应用程序的位置。



我认为你做的事情比必要的要复杂得多。




可能。如果我是,我将很高兴知道一个更简单的解决方案。 (我

意思是简单的代码,而不是简单的解释。)

这个问题已经解决了吗?有没有一个地方我可以寻找现成的解决方案?



只需循环进行你的i / o(无论如何都要这样做)。 />究竟如何计算换行符取决于您用于i / o的功能。例如。如果您使用cin.get(),请检查其'/ \\ n''的返回值。如果您使用例如''std :: getline'',当它返回时,你知道你遇到了换行符,或者说是EOF(或发生了错误)。你可以用以下方法理清发生的事情。 ''eof()''和''fail()''




嗯,如果我正在阅读像字符这样的原始值,那就没关系br />
行。但即使使用>>读取整数会让我遇到麻烦

因为它会消耗空白而没有机会让我去检查它。而且我在想一下read-opaque-object

的情况。


检测我使用的所有I / O例程会减少它们的封装和

使它们更难阅读,我相信它会容易出错。如果

可以让流对象在内部跟踪我的信息

,它会(我相信)正常工作。


Adam H. Peterson写道:

我想创建一个流或streambuf来跟踪已读取的
行的数量和类似的东西(所以,对于例如,当我收到错误消息时,我可以向流询问行号并将其放入错误消息中。
这个问题已经解决了吗?我能找到一个地方吗?看看
的现成解决方案?


Boost Iostreams库,将包含在下一个版本的

Boost(1.33) ,可以很容易地将过滤器链连接到现有流和

流缓冲区。这些过滤器可以修改数据,或者只是观察它,就像在你的

情况下一样。我我打算添加一个计算换行符的过滤器,但还没有这样做

还没有。


这里''一个简单的过滤器,用于计算输入线(未经测试):


#include< boost / iostreams / concepts.hpp> // input_filter

#include< boost / iostreams / operations.hpp> //获取


使用命名空间std;

使用命名空间boost :: io;


class line_counter:public input_filter {

public:

line_counter():lines_(0){}

int lines()const {return lines; }


模板< typename来源>

int get(来源& src)

{

//传递字符不变。

int c = boost :: io :: get(src);

if(c ==''\ n'')

++ lines_;

返回c;

}

私人:

int lines_;

};


(这只是一个例子;官方版本将更有效率。)它

可以使用如下:


#include< iostream>

#include< boost / ref.hpp>

#include< boost / iostreams / filtering_istream.hpp>


using namespace std;

using namespace boost :: io;


int main()

{

line_counter counter;

filtering_istream in;

in。推(升压:: REF(计数器)); //推送到柜台的引用

in.push(cin);


//从''in'读取而不是''cin' 。计数器将计算行数。

...


std :: cout<< 从std :: cin ="读取的行<< counter.lines()<< " \ n";

}


写一个扩展filtering_istream的类也不是很容易

自动跟踪行数。


最新版本的库在这里:

http://home.comcast.net/~jturkanis/iostreams/


我打算很快更新。

Adam H. Peterson




最好的问候,

Jonathan


I would like to make a stream or streambuf that tracks the number of
lines that have been read and stuff like that (so, for example, when I
get an error message, I can ask the stream for the line number and put
it in error messages. I tried to create a streambuf class that held an
instance of another streambuf (through parameterized inheritance) and
would ferry calls from the one to the other, tracking data as it was
read, but I wasn''t able to get a hook that found where the data gets
passed to the calling application.

Has this problem already been solved? Is there a place I can look for a
ready-made solution?

Anyway, thanks for reading.

Adam H. Peterson

解决方案

"Adam H. Peterson" <ah**@email.byu.edu> wrote in message
news:cp***********@acs2.byu.edu...

I would like to make a stream or streambuf that tracks the number of
lines that have been read
You don''t need to create your own stream or
stream buffer type to do this.

Just count the newsline characters when you read.
and stuff like that

"stuff like that" is such a vague phrase, I won''t even
try to address it.
(so, for example, when I
get an error message, I can ask the stream for the line number and put
it in error messages.
Output the value of a counter which you increment when
encountering a newline character.
I tried to create a streambuf class that held an
instance of another streambuf (through parameterized inheritance) and
would ferry calls from the one to the other, tracking data as it was
read, but I wasn''t able to get a hook that found where the data gets
passed to the calling application.
I think you''re making things far more complex than necessary.

Has this problem already been solved? Is there a place I can look for a
ready-made solution?



Just do your i/o in a loop (typical way to do it anyway).
Exactly how you count newlines depends upon the functions
you use for your i/o. E.g. if you use cin.get(), check its
return value for ''\n''. If you use e.g. ''std::getline'', when
it returns, you know you''ve either encountered a newline, or
EOF (or an error occurred). You can sort out what happened
with e.g. ''eof()'' and ''fail()''

-Mike


Mike Wahler wrote:

"Adam H. Peterson" <ah**@email.byu.edu> wrote in message
news:cp***********@acs2.byu.edu...

I would like to make a stream or streambuf that tracks the number of
lines that have been read

You don''t need to create your own stream or
stream buffer type to do this.

Just count the newsline characters when you read.



This isn''t really useful to me, though. If I have code like:

void f(istream &i) {
Object o;
i >> o;
}

I don''t really want to poke around inside Object''s stream extraction
operator, and I may be unable to. It''s pretty common to have opaque I/O
routines that read and write objects or data structures of various
types. Often I can''t instrument them, and even if I can, it usually
results in pretty messy looking code when compared with the original.
So I don''t always have the option of keeping track of stuff as I read it
--- that is, unless I can get the stream to do it for me.

I tried to create a streambuf class that held an
instance of another streambuf (through parameterized inheritance) and
would ferry calls from the one to the other, tracking data as it was
read, but I wasn''t able to get a hook that found where the data gets
passed to the calling application.


I think you''re making things far more complex than necessary.



Possible. If I am, I would be grateful to know a simpler solution. (I
mean simple to code, rather than simple to explain.)

Has this problem already been solved? Is there a place I can look for a
ready-made solution?


Just do your i/o in a loop (typical way to do it anyway).
Exactly how you count newlines depends upon the functions
you use for your i/o. E.g. if you use cin.get(), check its
return value for ''\n''. If you use e.g. ''std::getline'', when
it returns, you know you''ve either encountered a newline, or
EOF (or an error occurred). You can sort out what happened
with e.g. ''eof()'' and ''fail()''



Well, that''s fine if I''m reading primitive values like characters or
lines. But even reading integers using >> will get me into trouble
because it will consume whitespace without an opportunity for me to
inspect it. And I''m thinking in general of the read-opaque-object
situation.

Instrumenting all the I/O routines I use reduces their encapsulation and
makes them harder to read, and I believe it would be error prone. If
the stream object can be made to track that information for me
internally, it would (I believe) just work.


Adam H. Peterson wrote:

I would like to make a stream or streambuf that tracks the number of
lines that have been read and stuff like that (so, for example, when I
get an error message, I can ask the stream for the line number and put
it in error messages. Has this problem already been solved? Is there a place I can look
for a ready-made solution?
The Boost Iostreams library, which will be included with the next release of
Boost (1.33), makes it easy to attach chains of filters to existing streams and
stream buffers. These filters can modify data, or simply observe it, as in your
case. I''m planning to add a filter which counts newlines, but haven''t done so
yet.

Here''s a simple filter for counting lines of input (untested):

#include <boost/iostreams/concepts.hpp> // input_filter
#include <boost/iostreams/operations.hpp> // get

using namespace std;
using namespace boost::io;

class line_counter : public input_filter {
public:
line_counter() : lines_(0) { }
int lines() const { return lines; }

template<typename Source>
int get(Source& src)
{
// Pass characters through unchanged.
int c = boost::io::get(src);
if (c == ''\n'')
++lines_;
return c;
}
private:
int lines_;
};

(This is just an illustration; the official version will be more efficient.) It
could be used as follows:

#include <iostream>
#include <boost/ref.hpp>
#include <boost/iostreams/filtering_istream.hpp>

using namespace std;
using namespace boost::io;

int main()
{
line_counter counter;
filtering_istream in;
in.push(boost::ref(counter)); // Push a reference to the counter
in.push(cin);

// Read from ''in'' instead of ''cin''. counter will count the lines.
...

std::cout << "lines read from std::cin = " << counter.lines() << "\n";
}

It''s also not fairly easy to write a class extending filtering_istream which
keeps track of the line count automatically.

The most recent version of the library is here:

http://home.comcast.net/~jturkanis/iostreams/

I plan to update it soon.
Adam H. Peterson



Best Regards,
Jonathan


这篇关于跟踪输入流中的信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆