一、文件的输入输出
头文件fstream定义了三个类型支持文件IO:ifstream从给定文件读取数据、ofstream向一个给定文件写入数据、fstream读写给定数据。这些类型与cin和cout的操作一样,我们可以用IO操作符来读写文件,还可以用getline从一个ifstream读取数据。
1、getline()函数
getline的函数原型为:
istream& getline(istream& is, string& str, char delim);
istream& getline(istream&& is, string& str, char delim);
istream& getline(istream& is, string& str);
istream& getline(istream&& is, string& str);
通常我们使用getline函数读取一整行,该函数接受一个输入流和一个string对象,函数从给定的输入流中读取内容,直到遇到换行符为止,然后将所读的内容存入到个string对象中。
另外,当函数为istream& getline (istream& is, string& str, char delim);形式时,函数遇到delim也会停止。
2、使用文件流对象
当我们想要读入一个文件时,可以定义一个文件流对象,并将对象与文件相关联起来,每一个文件流类都定义了一个名为open的成员函数,完成一系列系统相关的操作。
open函数的原型为:
void open (const char* filename, ios_base::openmode mode = ios_base::out);
void open (const string& filename, ios_base::openmode mode = ios_base::out);
文件模式(mode)有一下几种:
ofstream outfile("E:\\out.txt", ofstream::app);
上述代码打开out.txt文件,如果不存在,系统会创建此txt文件,并且定位到文件末尾。
打开的文件使用完成后一定要关闭, fstream 提供了成员函数 close() 来完成此操作。
例:从hello.txt文件中读取数据并写入到out.txt中
#include "stdafx.h"
#include <vector>
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
ifstream myfile("E:\\hello.txt");
ofstream outfile("E:\\out.txt", ofstream::app);
string temp;
if (!myfile.is_open())
{
cout << "未成功打开文件" << endl;
}
while(getline(myfile,temp))
{
outfile<<temp;
}
myfile.close();
return 0;
}
二、string流
string头文件定义了三个类型来支持内存IO,istringstream向string写入数据,ostringstream从string读取数据,stringstream既可从string读取数据也可向string写数据,就像string是一个IO流一样。
#include "stdafx.h"
#include <string>
#include <sstream> //使用istringstream所需要的头文件
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
string str = "I am a boy";
istringstream is(str);
string s;
while (is >> s)
{
cout << s << endl;
}
return 0;
}
输出结果为:
I
am
a
boy
例:编写程序,将来自一个文件中的行保存在一个vector<string>中,然后使用istringstream从vector读取数据元素,每次读取一个单词。
#include "stdafx.h"
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
vector<string> vec;
ifstream myfile("E:\\hello.txt");
string temp;
if (!myfile.is_open())
{
cout << "未成功打开文件" << endl;
}
while(getline(myfile,temp))
{
vec.push_back(temp);
}
for (auto it = vec.begin(); it != vec.end(); it++)
{
cout << *it << endl;
}
cout << "-----------------使用istringstream------------------------" << endl;
for (auto it = vec.begin(); it != vec.end(); it++)
{
istringstream record(*it);
string s;
while (record >> s)
cout << s << endl;
}
return 0;
}
运行结果如图所示:
//下述论述转自www.cndev-lab.com ,程序作者:管宁
#i nclude <iostream>
#i nclude <sstream>
using namespace std;
int main()
{
istringstream istr;
istr.str("1 56.7",);
//上述两个过程可以简单写成 istringstream istr("1 56.7");
cout << istr.str()<<endl;
int a;
float b;
istr>>a;
cout<<a<<endl;
istr>>b;
cout<<b<<endl;
system("pause");
}
上例中,构造字符串流的时候,空格会成为字符串参数的内部分界,例子中对a,b对象的输入"赋值"操作证明了这一点,字符串的空格成为了整型数据与浮点型数据的分解点,利用分界获取的方法我们事实上完成了字符串到整型对象与浮点型对象的拆分转换过程。
str()成员函数的使用可以让istringstream对象返回一个string字符串(例如本例中的输出操作(cout<<istr.str();)。
ostringstream同样是由一个string对象构造而来,ostringstream类向一个string插入字符。
ostringstream的构造函数原形如下:
ostringstream::ostringstream(string str);
//下述论述转自www.cndev-lab.com ,程序作者:管宁
#i nclude <iostream>
#i nclude <sstream>
#i nclude <string>
using namespace std;
int main()
{
ostringstream ostr;
//ostr.str("abc");//如果构造的时候设置了字符串参数,那么增长操作的时候不会从结 尾开始增加,而是修改原有数据,超出的部分增长
ostr.put('d');
ostr.put('e');
ostr<<"fg";
string gstr = ostr.str();
cout<<gstr;
system("pause");
}
在上例代码中,我们通过put()或者左移操作符可以不断向ostr插入单个字符或者是字符串,通过str()函数返回增长过后的完整字符串数据,但值 得注意的一点是,当构造的时候对象内已经存在字符串数据的时候,那么增长操作的时候不会从结尾开始增加,而是修改原有数据,超出的部分增长。