第二章 stringstream的使用

如果按照内容来给一个标题的话,那么这一讲的内容其实是上一讲的后续部分,所以都属于C++标准流一类,但是又碍于我们这不是写书,而是按照文章来推送,所以这算是一个新的章节,然尽管如此,这依然算是C++的流的介绍,所以,在上一章文章中我们了解了C++标准流的用法后那么我们现在从文件流说起。

程序无非是数据的操作,最常用的莫过于数据的读写了,还记得我们在上一讲的内容中使用自定义的流扩展了一个文件流——FileOStream,该类继承至MyStrIobase,当然我们可以直接继承至OStream,好吧,想想为什么要继承至OStream,继承至OStream的优势又是什么。

我们不对FileOstream进行讨论,至少大家已经知道了C++标准流背后的一些原理,所以我们这一讲的内容将是站在上一讲的基础上来对fstream和stream的探索。

从fstream说起

在C++标准库中,fstream继承至iostream,所以iostream该有的操作他都有,fstream还具有iostream不具有的能力——文件的度读写。

如同上一讲的内容,文件的读写简单点说就是将数据发送到指定的目的地或者是从指定的地方将数据取回来,所以,我们可以这么来解读iostream所干的事——将这个目的地给固定了,而fstream却可以自由指定这个目的地——文件,对于文件我们可以使用构造函数来指定,同样可以使用open接口来重定向:

//+-----------------------

#include

int main(){

std::ofstream outFile("1.txt",std::ios::out);

outFile<

outFile.close();

outFile.open("2.txt",std::ios::out);

outFile<

outFile.close();

std::ifstream inFile("1.txt",std::ios::in);

std::string str;

std::getline(inFile,str);

std::cout<

inFile.close();

return 0;

}

//+------------------------

从上面的代码中,我们可以看到,我们可以通过构造函数来打开文件,同样也可以通过提供的成员函数open来打开文件,当我们写完数据之后我们可以使用close来关闭文件,关闭当前文件后又可以打开其他文件,ofstream用来将数据写入文件,ifstream用来从文件中读取,所以,有了第一章的基础后来使用fstream是非常简单的,当然或许我们要说说的是对于二进制文件的读写,对于二进制数据还记得我们上一讲中说到的write函数吗?

//+-----------------------

ostream& write(const char*,streamsize);

//+-----------------------

当时我们说这个函数可以用来处理字符串,其实它不只是能够处理字符串,他能够处理一切数据,为什么这么说呢?首先,它的第一个参数是一个char的指针,第二个参数是一个大小,而char*可以转换为任意数据的指针,同样任意数据都可以转换char*,比如:

//+-----------------------

int main(){

int a = 10;

char* ch = (char*)(&a);

int d = *(int*)(ch);

std::cout<

return 0;

}

//+-----------------------

我们将一个int的对象存储在一个char*中然后又再取出来,数据得到很好的还原。我们再来看一些更为复杂的:

//+-----------------------

struct Test{

int a;

double b;

long long c;

};

int main(){

Test test = {10,20.0,1000LL};

char* ch = (char*)(&test);

Test test2 = *(Test*)(ch);

std::cout<

std::cout<

std::cout<

return 0;

}

//+------------------------

就算是复合类型也毫无问题,那么我们是不是明白了write这个函数对于数据的读写能力的强大之处了呢?所以当我们要保存或是恢复一个对象的时候可以如下操作:

//+-----------------------

struct Test{

int a;

double b;

long long c;

};

int main(){

Test test = { 10, 20.0, 1000LL };

std::ofstream outFile("1.txt", std::ios::binary | std::ios::out);

outFile.write((char*)(&test), sizeof(Test));

outFile.close();

std::ifstream inFile("1.txt", std::ios::binary | std::ios::in);

char* ch = new char[sizeof(Test)];

memset(ch, 0, sizeof(Test));

inFile.read(ch, sizeof(Test));

inFile.close();

Test test2 = *(Test*)(ch);

std::cout << test2.a << std::endl;

std::cout << test.b << std::endl;

std::cout << test.c << std::endl;

return 0;

}

//+------------------------

我们可以将一个对象存储在硬盘里面需要的时候可以将他恢复出来,这就是fstream的write和read的妙用。上一讲我们并没有接触过read,那么read函数的原型如下:

//+-----------------------

ifsteram& read(char*, streamsize)

//+-----------------------

该函数的功能是从流中读取指定大小的字节数据,数据填充在指定的地方——第一个参数指定的地址。

至此,使用C++读写文件对我们来说已经是很轻松的事了,那么接下来我们来看看在C++流中我认为算是一个很高级的东西——stringstream。

stringstream,顾名思义就是字符串流,对于不少C++程序员来说这个这个组件可能用得比较少,或许可能很多人没听说过,比如就我就遇到有人不知道该流的存在,更别说用法了,因为这东西实在用得比较少,而且如果只是普通的使用C++的话stringstream是可以完全无视的。噢……既然可以被无视的东西为什么我们这里要说呢?而且更是将stringstream的使用来作为这一章的标题。好吧,原因很简单,在我看来stringstream虽然不常用,但并不表示它没用。

设想一个场景,假如有两个函数,两个函数需求的参数类型各不相同,但如今我们会用到这两个函数,为了简便操作,我们将两个函数封装成一个函数:

每天会更新论文和视频,还有如果想学习c++知识在晚上8.30免费观看这个直播:https://ke.qq.com/course/131973#tuin=b52b9a80


分享到:


相關文章: