标签存档: C++

sinablog2wordpress:从新浪博客搬家到WordPress

Screenshot

要从新浪搬到Wordpres,网上广为流传的方法是利用blogbus的博客搬家服务获得blogbus格式的xml,然后再用一个Python写的脚本把它转换成WordPress认识的格式。但是这种方法在最近新浪博客升级以后就失效了。于是自己用现学的scala写了一个小程序,搬家时能保留标签目录评论评论回复这些信息。

猛击[这里]下载。注意,此程序仅支持2010年初的新版新浪博客,之前或之后的版本都不支持。

要运行程序,你需要确保已经安装过JRE。双击运行后显示如图界面,填入自己的博客地址(不要省略“ http:// ”),然后点击“Start”即可。这时“Start”按钮变为灰色,标题栏显示“Extracting”。等待几分钟,当标题栏显示为“Done”、“Start”按钮重新变为可用时,程序所在目录下会出现一个blog.xml文件。把这个文件直接导入WordPress就可以了。

代码也打在jar包里了,MIT协议。欢迎报告bug。

下面是废话。

恩由于新浪用了ajax,评论信息是通过xhr异步读取的,用一般的方法没法抓到。我纠结许久,最后是用了非常ad hoc的方法解决的,不知道有没有什么什么不太麻烦的通用解决方案呢。

再扯两句scala。我都想不起来当初具体是怎么想到要学scala的,也许是为了了解下函数式编程,也许只是想在jvm上有一个喜欢的语言吧——Java写起来太不爽了;Java社区的低效和保守也已经开始显出C++的影子。

scala确实是非常强大和灵活;我在见到一些颇富技巧性的hack之后都有些怀疑scala社区的风气会不会慢慢变得像C++社区一样过分热衷技巧的炫耀。不过scala的设计目标就是以较简单的语法规则获得最大的scalability,不需要通过挖掘语言规范里的犄角旮旯来实现一些必要功能,所以不会像C++一样成为一门本身已相当复杂,却还需要别人反过来教语言发明者如何使用的语言。

scala毕竟表现力比Java强太多,代码也简洁太多。比如这次我需要实现一个抛出异常后重试若干次的逻辑,只需定义一个函数:

def tryFor[T](times: Int)(op: => T): T = {
  if (times <= 0) throw new RuntimeException("Operation failed.")
  try { return op } catch {
    case e: Throwable => e.printStackTrace
    tryFor(times - 1)(op)
  }
}

然后这样使用:

val source = tryFor(5) {new Source(url)}

程序就会不断获得网页源代码,并在5次失败后抛出异常。Java实现同样的东西可不会如此优雅了。又如下面这段代码返回一篇博文xml:

private def generateEntryXml(entry: BlogEntry) = {
  <item>
    <title>
      {entry.title}
    </title>
    <wp:post_date>
      {dateFormat.format(entry.postDate)}
    </wp:post_date>
    <category>
      {entry.category}
    </category>
    {for (tag <- entry.tags) yield <category domain="tag">{tag}</category>}
    <content:encoded>
      {xml.Unparsed(handleNewLines(entry.content))}
    </content:encoded>
    <wp:status>publish</wp:status>
    {for (comment <- entry.comments) yield generateCommentXml(comment)}
  </item>
}

注意,xml标签直接作为scala的源代码的一部分在代码中出现!虽然我觉得这样会使scala语言多出一种“特殊情况”,增加语言的复杂性,但不得不承认这样的设计确实非常优美简洁。

我比较看好scala,以后自己做跑在jvm上的东西scala应该是首选语言。推荐有兴趣的童鞋也了解一下。

小试模板元编程

很久不更新了,再水一下吧。

前两天新开的数据结构课布置上机作业,里面又出现了不知道之前出现过多少次的输出质数。每次都交表也会很乏味,所以……这次还是要交表 – -||| 不过要玩一点小花样——让编译器在编译期把质数表算出来。

这个当然涉及到一点模板元编程了。之前虽然看了《Effective C++》里关于模板元的简介挺感兴趣,但看到《学习C++:实践者的方法》里告诫不要在这种“20%场景下的复杂性”上白花时间(“这些细节或技术在日常编程中极少用到,尤其是各种语言缺陷衍生出来的workarounds,构成了一个巨大的长尾……绝大多数只在库开发当中需要用到”),我一直对模板元编程敬而远之。这次也只是消遣一下,并无深入学习的打算。

以下是代码:

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

std::vector<int> Primes;

template <int toTest, int factor> // factor should be odd
class IsPrime
{
   public:
      enum {
         result = ( toTest == 2 )
         ||  toTest % factor
          && IsPrime < toTest , factor - 2 >::result
      };
};

template<int toTest>
class IsPrime<toTest, 1>
{
   public:
      enum {result = ( toTest == 2 )  || ( toTest & 1 ) };
};

template <int upperBound> // upperBound should be odd or 2
class PrimePick : public PrimePick < upperBound - 2 >
{
   public:
      enum {
         isPrime = IsPrime < upperBound, ( upperBound >> 1 ) | 1 >::result
      };
      PrimePick<upperBound>() {
         if ( isPrime )
            Primes.push_back ( upperBound );
      }
};

template<>
class PrimePick<2>
{
   public:
      PrimePick<2>() {
         Primes.push_back ( 2 );
      }
};

template<>
class PrimePick<1> : public PrimePick<2> {};

int main()
{
   PrimePick<999> PrimeInitializer;

   int m;
   std::cin >> m;
   for ( int i = 0; i < m; ++i ) {
      int n;
      std::cin >> n;

      std::vector<int>::iterator end = Primes.begin();
      while ( end != Primes.end() && *end <= n )
         ++end;

      std::ostream_iterator<int> out ( std::cout, " " );
      std::copy ( Primes.begin(), end, out );
      std::cout << std::endl;
   }
}

原理比较简单,主函数第一行初始化 PrimeInitializer 时,由于继承关系,构造函数会层层递归调用,从里至外利用另一个模板类 IsPrime 判断模板参数是否是质数,并把测试确认的质数放进一个 vector 里,这样就得到了编译期计算出的质数表。IsPrime 则使用最原始的试除方法判断质数。代码里一些写得很纠结的地方,一方面是为了尽量简化计算,减少编译时间,另一方面更主要是因为 g++ 默认最大只能实例化500层模板,以题目的数据规模(1000)不纠结一下编译器会抱怨。

这个程序……很不幸没能 AC。Buaa 的 OJ 在设计时估计就考虑了这种情况,对编译时间做出了限制,在编译20秒左右还没编译成功时会结束编译,直接判 CE……这个程序在我的系统上编译需要20分钟(VC 编译)到半个小时以上( g++ 编译)的时间,冬冬的64位 Ubuntu 上用 g++ 编译也需要将近10分钟时间。如果OJ不做这个限制估计会像当年vijos一样pending很多页吧……

恩,第一次模板元编程经历就以这样悲惨收场了 T_T

更新:

vijos果然被卡住了 – -

http://upload.tomtung.com/img/vijos-puppy-stuck.jpg

可怜的puppy

已作为bug报告。

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

std::vector<int> Primes;

template <int toTest, int factor> // factor should be odd
class IsPrime
{
public:
enum {
result = ( toTest == 2 )
||  toTest % factor
&& IsPrime < toTest , factor – 2 >::result
};
};

template<int toTest>
class IsPrime<toTest, 1>
{
public:
enum {result = ( toTest == 2 )  || ( toTest & 1 ) };
};

template <int upperBound> // upperBound should be odd or 2
class PrimePick : public PrimePick < upperBound – 2 >
{
public:
enum {
isPrime = IsPrime < upperBound, ( upperBound >> 1 ) | 1 >::result
};
PrimePick<upperBound>() {
if ( isPrime )
Primes.push_back ( upperBound );
}
};

template<>
class PrimePick<2>
{
public:
PrimePick<2>() {
Primes.push_back ( 2 );
}
};

template<>
class PrimePick<1> : public PrimePick<2> {};

int main()
{
PrimePick<999> PrimeInitializer;

int m;
std::cin >> m;
for ( int i = 0; i < m; ++i ) {
int n;
std::cin >> n;

std::vector<int>::iterator end = Primes.begin();
while ( end != Primes.end() && *end <= n )
++end;

std::ostream_iterator<int> out ( std::cout, ” “ );
std::copy ( Primes.begin(), end, out );
std::cout << std::endl;
}
}

初来北航一个多月的零零碎碎

http://upload.tomtung.com/img/reminder_look_at_reminder_wall.jpg

几乎持续忙碌中。得空扯两句。

除了多了不少限制,生活和来之前差不多。食堂挺好。大运村很贵,不过想想也就4年而已,也就无所谓了。没阳台,很不方便。房间里有小强出没让人很不爽,不过比去年在福州一中见到的要小多了,也没那么嚣张。还好能有自己的书桌,用无线路由上着网,看着书,其实还是很惬意的。恩……我其实还是很容易满足的。

室友都很好很强大,让我觉得笨鸟先飞格外必要。有点后悔假期没有看看数学,现在一周五节数学(三节高数两节离散)让人有点吃不消。尤其是高数,大半年没有怎么做过这种题,现在看着它们感觉脑子像卡住了一样……英语依旧荒废中,腾不出手来处理,所幸 RP 足够好进了 B 班。专业方面,终于还是失去了第二遍读完 C++ Primer 的耐心,这份读书笔记也不知何年何月才能完成了。转而开始看 Effective C++,看完那三本 Effective 就不再在 C++ 上过多纠缠了,什么模板元之类的都省省吧……这门语言的复杂程度已经足够让我望而却步了,抱着厚书啃啊啃也啃不完总不是办法,还是今后在实践中逐渐积累吧。《Pro C# with .NET 3.0 Special Edition》刚到第八章,《Head First Design Patterns》也到第八章。它们的阅读进度都由于要顾及数学被严重拖慢了,很让人郁闷。至于其它七七八八的科目,什么语文啊计算机导论啊历史啊政治啊航空航天概论啊,都在摸着石头瞎混中,但愿能混过去……

没参加任何类似学生会或者班委会的组织。社团仅仅参加了 MSTC(微软技术俱乐部),并且顺利混进 .NET 组。据冬冬说,我在面试时极为成功的装X竟然让某巨牛印象深刻并颇为赞许,这让我相当有成就感。如果顺利,不太久会参与项目开发。看来我放假时决定学 C# 还算明智。现在感觉 MSTC 还算不错。

本来准备参加的 GC(Google Camp)也顺利入围技术部,不过了解更多以后觉得很不靠谱,暂且退出免得浪费时间。

ACM/ICPC 终于还是没有去参加……恩,连新生的选拔赛都干脆没去。虽然这个决定是早在年初就做好的,心中还是免不了一丝不舍。希望我没有做出错误的选择。

之前参加了一次 Liunx of BUAA 北航小聚,用 Vista 的我只能拿本里的 andLinux 充数。群牛闪耀,气氛很融洽,更重要的是我和冬冬很幸运地遇到 Jesse,他是在北航举行的08年 Gnome 亚洲峰会主页)北航方面的负责人,然后我们就高高兴兴地成了志愿者。记得是蒋天正还是谁给我们说,你们刚来没几天就能参加国际会议了~~ 作为技术上太水的人,我也就只能搬搬桌子、指个路什么的,以此为开源社区做点贡献了。顺带一提,这样一个技术会议的组织者竟然是 Emily 姐和 Pockey 姐两位女性,真是奇妙。会议很成功,这里有n多大家拍的照片。以此为契机,北航的开源社团似乎也即将成立,真是件好事。

一段时间听了很多碟。周董的新专辑还不如上一张,周导演果然没时间玩音乐了;JJ的新专辑安排很杂,不过整体质量还算不错。重新开始听原来没什么感觉的门德尔松无词歌。又开始迷巴赫,重听了以前没有特别留心感受的曲子,从大无开始,到小无,然后是钢琴的帕提塔、意大利协奏曲等等,并且各同时找好几个版本对照。上课路上看着阳光透过教学区树木的树冠,随着欢欣的库兰特舞跳动,或者眯起眼睛依着一首萨拉班德打一会儿瞌睡,觉得生活真是美好。托卡塔从耳旁流过时似乎可以提神,严谨紧凑的赋格似乎也会潜移默化地帮助思考。温暖且踏实的大调诠释着幸福,清冷或宁静的小调表达着自省,二者交替间很容易就在我的心室中共鸣回响起来。从不滥情的巴赫总能让人在忙碌中保持安稳,我每过一段时间似乎都会到巴赫这里停靠。每次少则一周多则一两个月,总能得到珍贵的体验。

恩……似乎这段时间值得说的就是这么多。瞎忙之中一切看起来都在向着好的方向发展,一些小麻烦还不足以影响心情。希望一切顺利。

最后,祝贺银男 Ghost 终于银了。祝高三各位大牛保送顺利。欢迎报考 BUAA。

写在临行前

昨天终于顺利闹完了,20号开学,今晚的火车,明天到。

如果从年初学校定下来开始算起,到现在,那真是有大半年的假期了。虽然基本上一直都是忙忙碌碌的,但是效率并不咋高。假期开始的时候没写什么假期计划,现在就写点总结吧。

E文的重要性我是清楚的,自己清楚确实需要加强。原来有人(好吧,我坦白,包括我自己)觉得我英语不错,其实现在客观地看,不过是几句简单的说得比较溜,能吓唬下不了解情况的人而已,其实在基础各方面问题非常多。

我差不多是从今年4月份开始重新拾起E文的。兰州找不到合适的班,就自己跟着一个叫《彭蒙惠英语》的杂志走。这个是空中英语教室系列的高级版,对我来说比较吃力,但是中级版又太EZ,只好勉强用这本,结果每个月甚至都没有精力看完当月的内容。4~8月读过的课文篇数分别为2、6、7、8、1,可见利用率并不高。

当初其实规划得挺好:每天都安排课文和配套广播,可以练阅读和听力;遇到的生词记下来可以提升词汇量;另外还在网上找到了语音讨论组可以练习口语。这样就可以全面提高了。但是对我来说杂志内容难度实在偏大,每天都要花费不少时间。每天如果读课文至少需要半小时,预习半小时,广播节目半小时。口语练习一小时。生词仅一共背了 2000左右(更不幸的是现在已经忘掉不少了),难度等级从小学初中到专八GRE都有(可见我野路子学上来的基础确实有问题),每天按照软件安排复习和初记至少半小时。这样算下来单单是英文每天就要最少花费3小时,哪天稍微耽搁后面进度就跟不上了,煞是郁闷,到最后就干脆坚持不下来了。现在还是没有真正找到合适的英语学习方法,比较愁,哪位同学有什么建议欢迎在下面评论。

数学看得不多,除去已经忘掉的就可以忽略不计了……

专业课方面,主要是看完了一本C#和对象建模的入门书,以及C++ Primer。前者非常基础,需要深入起码还要看好几本。后者,正如我在这里所说的,花了超出预期很多的时间才看完第一遍,第二遍也没能在开学前看完。本来原计划是在开学前不但看完Primer,还要看完那三本Effective的,彻底搞定明年新标准发布前我需要掌握的C++内容。已经完成的部分和计划相比差太多了。

学会了游泳。

自学一点钢琴,教材用599和哈农,从高考开始学到现在,各只弹到第15首。买的琴是Yamaha DGX-620,本来想带去学校继续学的,结果发现我根本没有理解20公斤意味着什么……况且宿舍小也不一定能放得下。原来所谓Portable Grand的意思仅仅是相对Grand稍微Portable 一点而已了。查了下其它的电钢,似乎真正比较Portable的键盘都不带配重……那就先算了吧。

恩……大致就是以上这些了。Linda姐问我假期最大的成果是什么,我说不知道……各项都不满意。忙忙碌碌但不出效果。其实把C++和E文放在一起的安排是很失败的,一天到晚都在看语言上拉拉杂杂的东西,搞得人又烦又低效。。。

忙忙碌碌的,看起来那么长的一个假期也就这样过去了。昨天去一中,见了老赵、DF、野牛、格格他们,又在楼道里习惯性闲逛,在二球下习惯性驻足,在公交站台上习惯性无意义等待。即将满载着回忆离开,除了少了很多熟识的面孔,那里的一切都还是一样熟悉。

之前同学陆陆续续都走差不多了,并没有太多离别的伤感。我只是觉得大家保持着联系就好,有缘也肯定还会再见。我似乎总是习惯看好现在,看好将来,并不太多留恋身后。想想旅行时我不喜欢拍很多照片留念可能也是这个原因吧。是豁达,是冷漠,还是不知珍惜,我自己无从分辨。我一直自以为是前者,只是昨天从姥姥家回来才产生了怀疑。

姥姥快八十岁了,坚持要在我走之前看看我。她对我絮絮叨叨了很多已经说过很多遍的事情,然后让我常给她打电话。我们都笑着说姥姥拿起电话就豆腐三碗、三碗豆腐说个没完没了了,长途话费下来肯定把人愁死。姥姥摇着头说,她知道长途花费贵,又说我学习紧张,又说宿舍里那么多人也影响别人,只要我每周周末晚上打个电话就行了,她就和我说一句话,就一句,说好着呢,听听我的声音马上就挂掉……一边说用手掌抹着已经发红的眼眶。我们赶紧解释说长途花费是按时间计的,没有那么贵,学习也并没有那么紧张,也不会打扰到别人。姥姥还是摇着头说没事的时候多休息不要打电话,每周打一次电话,说一句话听听我的声音就行了,就一句话就行了……絮叨地这么说了很多遍。

我有些不知所措,突然间感到亲人对自己如此强烈的不舍。看着姥姥发红的双眼,我突然觉得不忍离去。这是一种我其实一直没有真正明白的情感,曾经很多老师对此的解释都是“等你们做父母、祖父母了就明白了”。作为一个自私的独生子女,我想我并没有真正懂得什么是爱。

我只是愣在那里,不断提醒自己记得多打几个电话。除此之外我不知道还能做到什么。

Unable To Stay, Unwilling To Leave. 不管怎样,几天以后就是完全不同的生活了。


C++ Primer 读书笔记 – 第八章

[笔记索引]

第8章 标准IO库

⒈ IO标准库类型
类名           派生自            头文件       描述
istream        ios               iostream   输入流
ostream        ios               iostream   输出流
iostream       istream和ostream  iostream   输入/输出流
ifstream       istream           fstream    输入文件流
ofstream       ostream           fstream    输出文件流
fstream        iostream          fstream    输入/输出文件流
istringstream  istream           sstream    输入字符串流
ostringstream  ostream           sstream    输出字符串流
stringstream   iostream          sstream    输入/输出字符串流

⑴ 标准库分别实现了以上继承层次的的两个版本,分别面向 char 类型(如上)和 wchar_t 类型
后者采用和前者一样的命名规则,仅在每个类和对象名前加上字母w以示区别
⑵ IO对象不可赋值或赋值

⒉ 标准输入输出对象
extern istream cin; 标准输入流
extern ostream cout; 标准输出流
extern ostream cerr;  标准错误输出流
extern ostream clog; 标准日志输出流

⒊ 文件输入输出流
⑴ 使用 ifstream, ofstream 和 fstream 型对象可以实现对文件的读写
⑵ 可以调用公共成员函数 open 或在创建时使用构造函数使流对象关联到一个文件
二者都接受两个参数:一个C风格字符串表示文件名,一个可选的 ios_base::openmode 型值表示流打开模式
① openmode 是用以表示流打开模式标识的位掩码类型,支持位操作符
该类型对象的值可以是以下打开模式标识或它们之间进行位操作所得的结果
和以下(openmode 型)模式标志均为 ios_base 的公共成员
Ⅰ app (append)每次执行输出操作前都定位到流的末尾
Ⅱ ate (at end)打开时定位到流末尾
Ⅲ binary 在二进制(而非文本)模式下操作
Ⅳ in (input)允许输入操作
Ⅴ out (output)允许输出操作
Ⅵ trunc (truncate)抛弃流中现存的所有内容,打开时假定长度为0
(openmode 和上述标识分别是 ios_base 的公共成员类型和公共成员常量)
② fstream 默认使用 in | out 模式
ifstream 自动使用 in 模式
ofstream 自动使用 out 模式(效果上等同于 out | trunc)
⑶ 完成文件操作后可以使用公共成员函数 void close() 关闭
关闭后可以再次 open 新文件,但之前应调用 clear 清除该流的状态
流对象被析构时也会自动调用 close()

⒋ 字符串流
⑴ 常用于特定数据类型和格式化的字符串之间的相互转换
3个类的构造函数各有带或不带 string 形参的两个不同版本
使用带 string 参数的版本,则创建储存该实参副本的字符串流对象
3个类的都有公共成员函数 str,它的两个版本分别返回和设置与该流对象相关的 string 对象
string str() const;
返回与该流对象相关的 string 对象
string str(const string&);
将该流对象相关的 string 对象设置为实参的副本

⒌ 条件状态
⑴ 流对象内都用一个 iostate 型值表示条件状态
· iostate 是用以表示流错误状态标志的位掩码类型,支持位操作符
该类型对象的值可以是以下条件状态标识或它们之间进行位操作所得的结果
Ⅰ eofbit 输入操作中遇到文件结束符(同时会设置failbit)
Ⅱ failbit 输入操作失败(通常可恢复)
Ⅲ badbit 流被损坏(通常不可恢复)
Ⅳ goodbit 没有错误,值为0
(iostate 和上述标识分别是 ios_base 的公共成员类型和公共成员常量)
⑵ 查询条件状态
bool ios::eof() const;
eofbit位被设置则返回 true, 否则返回 false
bool ios::fail() const;
failbit 或 badbit 位被设置则返回 true, 否则返回 false
bool ios::bad() const;
badbit 位被设置则返回 true, 否则返回 false
bool ios::good() const;
流对象有效则返回 true, 否则返回 false
ios_base::iostate rdstate() const;
返回当前条件状态
⑶ 控制条件状态
void ios::clear( ios_base::iostate = goodbit);
使用参数值替换当前条件状态
void ios::setstate( ios_base::iostate );
将参数状态加入当前状态(如同使用了位或操作符|)
⑷ 可以直接检查流对象的真值来确认是否可用

⒍ 输出缓冲区的管理
每个IO对象都管理一个缓冲区,作为流和写入目标间的媒介
下面几种情况将导致输出流被刷新(即写入到真实的输出设备或者文件)
⑴ 程序正常结束或目标文件被关闭
注: 程序崩溃不会刷新缓冲区
调试崩溃的程序时如果用最后的输出定义错误位置,应确保缓冲区已刷新
因此输出时应多使用endl而非‘\n’
⑵ 当缓冲区满时会自动刷新
⑶ 使用操纵符显式刷新缓冲区
(以下均定义在<ostream>中)
① endl 输出换行符并刷新缓冲区
② flush 刷新缓冲区(不添加任何字符)
③ ends 输出空字符‘\0′并刷新缓冲区
注:cplusplus.com,cppreference.com和msdn上都没有表示ends会刷新缓冲区,存疑
⑷ 使用 unitbuf 操纵符可以设置流对象的相关格式状态标志,使缓冲区在每次插入操作后都刷新
使用 nounitbuf 操纵符可以恢复为正常的、系统控制的缓冲区刷新方式
⑸ 可以把流对象绑定到一个输出流对象,前者进行任何I/O操作都会刷新后者
① 可以使用 ios::tie 公共成员函数查询、修改绑定状态
ostream* ios::tie() const;
返回指向所绑定到的输出流对象的指针
ostream* ios::tie( ostream* );
绑定到参数中指针指向的输出流对象(实参为0则解除绑定),并返回指向原绑定对象的指针
② cin, cerr, clog 默认绑定到 cout, 而它们的宽字符版本则默认绑定到 wcout

⒎ 控制格式状态
istream/ostream(及它们的派生类)对象都支持使用提取操作符(>>)/插入操作符(<<),从流中提取/向流中插入格式化的对象数据
把提取/插入操作符和一些操纵符(manipulator)一起使用,可以改变流对象的特性或格式设置
其中除setbase,setprecision,setw,setfill定义在头文件<iomanip>中外,其余操纵符均定义在<ios>中
⑴ 布尔值格式
从流中提取/向流中插入布尔值时形式使用 0, 1(默认) 还是 false, true
· 使用操纵符 boolalpha noboolalpha
⑵ 整数格式
① 基数设置
从流中提取/向流中插入整数时使用八进制、十进制(默认)还是十六进制
· 使用操纵符 oct dec hex
· 使用操纵符 setbase(int) (实参只能是8,1016)
② 基数前缀设置
向流中插入整数时是否显示基数前缀(八进制的0和十六进制的0x)(默认不显示)
· 使用操纵符 showbase noshowbase
③ 十六进制和科学计数法中字母的大小写设置
向流中插入整数时若使用十六进制或科学计数法,出现的字母使用小写(默认)还是大写
· 使用操纵符 uppercase nouppercase
⑶ 浮点数格式
① 精度设置
向流中插入浮点数精度为多少(默认为6)
· 使用 ios_base 的公共成员函数 precision 可以获得和设置流的浮点数精度
streamsize precision() const;
返回流对象的浮点数精度
streamsize precision( streamsize );
设置流的浮点数精度为实参值并返回先前的精度值
· 使用操纵符 setprecision( streamsize )
以上 streamsize 为表示流中大小的实现类型,是一个带符号基本整型的别名
注: 精度的解释在使用不同情况下不同
· 默认情况下解释为最大有效数字(位数不足不用小数末尾的零补齐)
· 在强制使用fixed,scientific或showpoint时解释为小数点后的确切位数(位数不足则用小数末尾的零补齐)
② 计数法设置
向流中插入浮点数时,让系统自动选择计数法(默认),还是强制指定为定点计数法或科学计数法
· 使用操纵符 fixed scientific
· 计数法不存在恢复默认的操纵符,但可以通过给成员函数 unsetf 传入常量 floatfield 达到目的
(unsetf 和 floatfield 均为 ios_base 的公共成员)
③ 小数点显示设置
向流中插入浮点数时,若小数部分为0,是否显示小数点和小数部分的0(默认不显示)
· 使用操纵符 showpoint noshowpoint
④ 非负数(整数和浮点数)正号设置
向流中插入非负数(包括0)时是否显示正号+ (默认不显示)
· 使用操纵符 showpos noshowpos
⑷ 对齐和填充格式
① 使用操纵符 setw( streamsize ) 可指定下次对流的插入操作的最小字段长度
注: 和endl一样,它不改变流的内部状态,只影响下一个输出
② 使用操纵符 setfill( char ) 设置向流中插入对象时用来填充字段的字符(默认为空格)
③ 字段内对齐方式设置(默认左对齐)
· 使用操纵符left right internal
关于internal:
- 对数值表示左对齐前缀(正负号和十六进制的0x)右对齐数值
- 对非数值则与 right 等效
⑸ 空白字符的处理
· 使用操纵符 skipws noskipws 设置从流中提取对象时是否忽略空白字符(默认忽略)
· 使用操纵符 ws 忽略输入序列中从当前位置开始尽可能多的空白字符,直到遇到非空白字符才停止
当然,如果已经(默认)设置了 skipws 则没有必要使用 ws

⒏ 无格式I/O操作
⑴ 单字节操作
① istream& get ( char& );
istream 的公共成员函数,从流中提取一个字符存入实参中
int get( );
无参数版本从流中提取一个字符并返回其值
② ostream& put ( char );
ostream 的公共成员函数,将字符参数值写入输出缓冲区并返回*this
③ istream& putback ( char );
istream 的公共成员函数,将字符参数值放回流中并返回*this
④ istream& unget ( );
istream 的公共成员函数,将流退回1字节并返回*this
int peek ( );
istream 的公共成员函数,读取并返回流中的下一个字符,但不提取它
注: 为允许返回EOF,put(无参数版本)和peek的返回值都为 int
⑵ 多字节操作
① istream& get (char* s, streamsize n, char delim );
istream 的公共成员函数,不断从流中提取字符并以字符串形式存入s指向首地址的数组,
直到出现以下情况之一:
- 已经提取了(n-1)个字符;
- 遇到了定界字符delim(如果不提供此参数则为‘\n’);
(被找到的定界字符不会被提取,而是继续留在流中作为下一个要被提取的字符)
- 到达文件末尾;
- 提取过程中发生错误;
最后返回*this.
注: 提取的字符以字符串的形式储存,故将自动添加结尾的‘\0′,而被提取的最大字符数也为(n-1)而非n
② istream& getline (char* s, streamsize n, char delim );
istream 的公共成员函数,与上面参数表相同的get版本类似,唯一区别在于定界字符会被提取并丢弃
③ istream& read ( char* s, streamsize n );
istream 的公共成员函数,从流中提取n个字符存入s指向首地址的数组,
直到出现以下情况之一:
- 已经提取了n个字符
- 到达文件末尾(eofbit和failbit会被设置)
- 提取过程中发生错误
最后返回*this.
注: 与get和getline不同,read不把提取的字符保存为字符串,故不会自动加上‘\0′
④ streamsize  gcount ( ) const;
istream 的公共成员函数,返回上次无格式输入操作提取的字符个数
(peek, putback, unget不提取字符,故对此gcount返回0)
⑤ ostream& write ( const char* s , streamsize n );
ostream 的公共成员函数,把s指向首地址的数组的前n个字符写入输出流缓冲区
⑥ istream&  ignore ( streamsize n = 1, int delim = EOF );
istream 的公共成员函数,从流中提取并抛弃字符,直到:
- 已经提取了n个字符或遇到了定界字符delim(该字符不会被提取)
最后返回*this.

⒐ 流的随机访问
⑴ 用于随机访问的成员函数
· pos_type tellg ();
pos_type tellp ();
返回输入/输出流中的标记当前的绝对位置
· istream& seekg ( pos_type pos );
ostream& seekp ( pos_type pos );
将输入/输出流中的标记重新定位至参数值表示的位置
· istream& seekg ( off_type off, ios_base::seekdir dir );
ostream& seekp ( off_type off, ios_base::seekdir dir );
将输入/输出流中的标记重新定位至距离dir偏移量为off的位置
⑵ 关于上述函数参数和返回值的类型
① pos_type和off_type都是类的成员类型,分别表示流中的标记位置和偏移量
后者可正可负,分别表示向前和向后偏移
② seekdir类型用来表示偏移的启示位置,其可能值如下
beg 流的开头
cur 流的当前位置
end 流的末尾
⑶ 以上tell和seek版本分别有两个版本g(get)和p(put)
其区别在于g版是istream类的成员,而p版是ostream类的成员
对于iostream对象,而者都适用,它们都操作同一个标记(而非输入输出各一个)
⑷ 普通iostream对象一般不允许随机访问,以上内容主要适用fstream和sstream

标签云

豆瓣