分享
 
 
 

对话:#09 重定向

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

[声明]:本英文资料源自于Herb Sutter 创建的“Conversation”栏目,“C++ 翻译小组”的翻译作品供学习交流与参考用途,不得用于任何商业用途。未经Herb Sutter、Jim Hyslop同意,不得转载;对于违反以上条款,翻译小组对此不负任何责任;特此声明。

文章来源:http://www.gotw.ca

版权归属:Herb Sutter and Jim Hyslop

译 者:csdnfriend(CSDN)

对话:#09 重定向

我开始并没太在意,但过了第三天还没见到珍妮,才感到不妙。一阵犹豫与绝望之后,我去找弗奈尔。找她是很自然的,因为我和珍妮当时都向她汇报工作。

当我敲第二下门的时候,房门打开了。“啊,是你,”她说。“什么事?”

“正在找珍妮,好几天没见她了。”我解释道。

弗奈尔扫了我一眼,说:“啊,是的。她最近分配了新的任务。”

“是吗,她在哪里呢?”

“在圆屋,那里和发掘现场都需要添加人手。她一旦去了就必须呆在那里了。去那儿是受限制的,因为门锁和地道情况不太好,进出那儿要穿特制的服装,真是痛苦。”

“是不是很多人都重新分配了任务?这里好像以后要搬空的样子。”我所知道的就是自从几周前的爆炸事件后,主圆屋那边显然还是一直在装修。表面上我们在外边的楼层里继续自己部门的工作,实际上与内部失去了联系,圆屋内大范围的通讯设施都有故障而在维修。

“有一些,”她说着靠在了门口边上。“为什么?如果需要你这样的,要我给你介绍进去吗?”

“当然,”我脱口而出然而又奇怪自己反应这么快。我这么惦记珍妮吗?或者我急着再见到她?不管怎样,感觉自己有点奇怪。

如果珍妮被转移到圆屋,我想如果有机会我也会去。忽然想起了很多年以前的一天,当时我学习处理另一种形式的转移。有意思的是,当时我也遇到了访问限制的问题。

- - - - - - - - - - - - - - - - - - - - - - - - -

正当温迪走过我的小卧室时,我正在大叫:“啊!我恨死非法访问了!”

挫折感太强烈了,我只想大喊大叫。然而我的声音终于烧焦般地减弱下去,最后变得和老鼠叫差不多了。

这一切已经足够使温迪停了来看我了。“你还好吧,怎么回事,年轻人?”她的语调里带有一点爱尔兰口音。随着圣.帕特里克节的临近,她的一举一动越来越象爱尔兰人。

“温迪,快帮我一个忙,”我叹了口气,“你用不着扮这副怪相,这里有一个怪人已经足够了。”

“喂,你还好吧?”她平静温和地说,“伙计,什么东西把你惹你这样?”

“啊呀,就是这些代码,我想可能和Guru有点关系。”我承认,“一开始我就被她吓得六神无主。我肯定她是从疯人院跑出来的。后来,我又有点喜欢她把我称作她的徒弟。是有点怪异,但也没什么大不了。但当我给朋友提起此事时,他们认为这是故意贬我。我再仔细回想一下,觉得他们说得没错。”

温迪笑了。“噢,”她说,“我明白了,事实上你没有从正确的着眼点去看待她。你应该去了解一下工作之外的她。”我试着想象她的家:架子上堆满了满是灰尘的电脑书和杂志;祭坛里烧着拜祭各位计算机科学家的香……我的神情一定出卖了我的想法—温迪大笑起来,“她摆Guru的架子,主要是为了气气鲍勃,吓唬一下新手。我喜欢她这样子,否则她就活象一具僵尸了。”

“哦。”我并没有被说服。我不置可否,我觉得Guru的举动还是有点出格。,但我不想跟温迪争,于是叹了口气静下来回到那个问题上:“我矛盾了几个小时了。任务很简单—实际上就是重定向cout和cerr,把它们输出到文件中。”

“好,把你做的再跟我说一下。”

“我正在整合另一个组开发的库。这个库是以命令行(接口)的思路写出来的,所以所有的调试、诊断信息送到了cout与cerr。更糟的是我认为鲍勃在那个组,因为没有一个规则及原因说明何时信息送到cout何时送到cerr。实际上,有些信息分开送到两个流上!所以我要跟踪它们并把它们凑在一个log文件里。”

“总之,正如我说的,我在把它们整合到我们的图形用户界面(GUI)应用程序里。不幸的是,GUI直接扔掉了cout和cerr的输出。所以,我正做的就是将输出转向到一个文件里,实际上,简单吧,简单得我不知该怎么做,我对问题进行分析过滤后,写了下面的小程序。”我拉了把椅子让温迪在电脑旁坐下。

#include <iostream>

#include <fstream>

int main()

{

std::ofstream logFile("out.txt");

std::cout = logFile;

std::cerr = logFile;

std::cout << "This goes to cout\n";

std::cerr << "This goes to cerr\n";

}

“程序在一个编译器上编译及运行没有问题,但换了个编译器就出了非法读取的错误。”

温迪看了看屏幕。“嗯…我不能确定你是不是可以那样重新分配数据流。”

“实际上,孩子,这样做显然极不自然明确地被神圣的标准所禁止。”

我们差点跳起来。不过怎么说,我得承认Guru总是神秘地在最恰当的时间出现。“所以,我这样做不行?”我叹道。

“不,” Guru微笑道,“,实际上很简单,徒弟,你在大学里用什么编译器?”

“噢,是一种很老的编译器,不支持标准的很多特性。”

Guru点点头。“我明白了。你的编译器应该在使用一种先知Langer 和 Kreft所谓的 经典输入输出流[1]。你肯定很熟悉标准输入输出流—尤其是流缓冲类。流缓冲不再是低级的实现上的细节;它现在是一个…完整的类。输入输出流的设计者,Jerry Schwarz 早就看到了流缓冲类将会成为一个极其有用的特性。然而它的价值和功能常常被忽略。”

“好吧。那我该怎么做呢?”

Guru拿起一枝干擦笔飞快地在白书写板上写下了如下的代码:

#include <iostream>

#include <fstream>

int main()

{

std::ofstream logFile("out.txt");

std::streambuf *outbuf = std::cout.rdbuf(logFile.rdbuf());

std::streambuf *errbuf = std::cerr.rdbuf(logFile.rdbuf());

// do the actual work of the program;

// GUI code and event loop would go here

std::cout << "This would normally go to cout but goes to the log file\n";

std::cerr << "This would normally go to cerr but goes to the log file \n";

logFile << "This goes to the log file\n";

// end of program body

// restore the buffers

std::cout.rdbuf(outbuf);

std::cerr.rdbuf(errbuf);

}

“rdbuf函数返回一个由基类basic_ios管理的流缓冲区的指针。重载版本允许你替换流缓冲区,返回值是原始的流缓冲区。解决方法很简单—用你的log文件的流缓冲区替换cout和cerr的流缓冲区。程序结束时,改回原来的流缓冲区。你可以看到,你仍能用logFile作为常规的输出文件。”

“酷毙了!”终于看到了流缓冲区的威力。“嘿,如果我只想重定向一个流,比如cerr,我是不是可以简单地交换这两个缓冲区,这样就无须担心怎样恢复它们了,象下面那样 :”

int main()

{

std::ofstream logFile("out.txt");

std::streambuf *saveBuf=cerr.rdbuf(logFile.rdbuf());

logFile.rdbuf(saveBuf);

// remainder of program...

}

“诶,并不这么简单,” Guru叹了口气 “这样的代码过不了编译关。basic_ios::rdbuf函数并不是虚拟函数。ofstream只提供了一个rdbuf函数,此函数没有参数,返回指向对象内部的文件缓冲流。也就是说

std::ofstream::rdbuf(void) 隐藏了 std::ostream::rdbuf(std::streambuf *)。

“你可以通过一个指向std::ostream的指针操纵你的log文件,如下:”

int main()

{

std::ofstream logFile("err.log");

std::ostream * baseManipulator = &logFile;

baseManipulator->rdbuf(std::cerr.rdbuf(baseManipulator->rdbuf()));

}

这些代码能通过编译,但无法正常工作。神圣的标准并没有规定ofstream的具体实现方法。有可能某种编译器实现了ofstream的功能而忽略了ostream::rdbuf函数,直接操作文件缓冲流。标准没有要求ofstream::close调用ostream:: rdbuf来决定闭哪个缓冲。因为此函数总是返回指向ofstream对象内部的filebuf,ofstream总会关闭自己内部的filebuf对象,于是cerr就没有了有效的缓冲区。所以,你还是要恢复原来cerr的流缓冲区,main退出前加入如下:

std::cerr.rdbuf(baseManipulator->rdbuf());

“如果你想重定向cin的输入,你必须预防类似的事情,ifstream也是这样的。”

Guru转身准备离开了,又停住了说:“这周六我想请人到我家来。没什么特殊的,一个交际晚会。欢迎你和温迪,及你们各自的朋友前来。”

我开口正准备优雅的谢绝。“啊!”

“他的意思是他很乐意过去,”温迪笑得很甜。我的小腿被她踹了一下,痛得厉害,只能含泪无助地点点头。Guru微笑着飘然而去。

我等Guru和疼痛都消失以后,对温迪大叫起来:“早晚修理你。”

- - - - - - - - - - - - - - - - - - - - - - - - -

“好啊,”我对弗奈尔说,“别忘了通知我一声。”

“好的”

我就要走了,又问了一句:“诶,林格没却那儿吗,我的意思是她和珍妮是搭档。”

“不,”弗奈尔说。“我们这里需要她。”

“谢谢。明天见。”

在下一个值班时,我核查了一下我允许看的职责花名册。名单很长,上面的名字各式各样。象Jupiter(木星)这样的名字归联合国管啊,所以这次任务肯定是联合国发起的。各个地方的人员都有,主要来自美利坚联合体和亚洲联盟,因为它们投入的科研经费最多。没有谁的名字被打个记号,表明已被重新分配任务。但我能看出哪些名字已不在花名册的日常值勤中了,他们肯定去别的地方了。

我慢慢看下去,看得很安静。

我终于发现了怪事:没有一个亚洲人被再分配到发掘现场或是圆屋。

[感谢]

感谢Angelika Langer和Klaus Kreft在他们的著作Standard C++ IOStreams and Locales: Advanced Programmer's Guide and Reference [1]中对这方面以及其它与流相关的话题作了清楚的讨论。

[注释]

[1] Angelika Langer and Klaus Kreft. Standard C++ IOStreams and Locales: Advanced Programmer's Guide and Reference (Addison-Wesley, 2000).

[关于作者]

Herb Sutter

是个独立顾问,也是ISO/ANSI C++标准委员会的秘书。你可通过hsutter@acm.org.联系他

Jim Hyslop

Leitch Technology International Inc.资深的软件设计师,你可通过jim.hyslop@leitch.com联系他

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有