C++中关于fstream和sstream的困惑

看C++ premier的时候遇到一个习题,不是很懂,最后经过查询资料似乎明白了,写下来留着以后不懂的时候再看看
先上代码吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//8-16.cpp
//将文件中的每一行存储在vector容器对象中
//然后使用istringstream
//从vector里以每次读一个单词的形式读取所存储的行
#include
#include
#include
#include
#include
using namespace std;

int fileToVector(string fileName, vector& svec)
{
//创建ifstream对象inFile并绑定到由形参fileName指定的文件
ifstream inFile(fileName.c_str());
if (!inFile) //打开文件失败
return 1;
//将文件内容读入到string类型的vector容器
//每一行存储为该容器对象的一个元素
string s;
while (getline(inFile, s))
svec.push_back(s);
inFile.close();//关闭文件
if (inFile.eof())//遇到文件结束符
return 4;
if (inFile.bad())//发生系统级故障
return 2;
if (inFile.fail())//读入数据失败
return 3;
}
int main( void )
{
vector svec;
string fileName, s;

//读入文件名
cout << "Enter filename :" << endl;
cin >> fileName;

//处理文件
switch (fileToVector(fileName, svec))
{
case 1:
cout << "error: can not to open file: "<< fileName << endl;
return -1;
case 2:
cout << "error: system failure " << endl;
return -1;
case 3:
cout << "error: read failure " << endl;
return -1;
}

//使用istringstream从vector里每次读一个单词的形式读取所存储的行
string word;
istringstream isstream;
for (vector::iterator iter = svec.begin();iter != svec.end(); ++iter)
{
//将vector对象的当前元素复制给istringstream对象
isstream.str(*iter);
//从istringstream对象中读取单词并输出
while (isstream >> word)
{
cout << word << endl;
}
isstream.clear();//将istringstream流设置为有效状态
}
system("pause");
return 0;
}

个人理解:因为函数的参数是string fileName所以需要使用c_str()转换成const char*型的,后面的那个相当于使用成员函数获取vector容器里面成员的string副本,然后和isstream绑定起来,然后以string形式输出每个单词。

关于这方面的一些相关知识,文件流对象的使用:需要读写文件时,则必须定义自己的对象,并将它们绑定在需要的文件上,假设ifile和ofile是存储希望读写的文件名的string对象,可如下编写代码:

1
2
3
4
//counstruct an ifstream and bind it to the file named ifile
ifstream infile(ifile.c_str());
//ofstream output file object to write file named ofile
ofstream outfile(ofile.c_str());

上述代码定义并打开了一对fstream对象。infile是读的流,而outfile则是写的流。为ifstream或者ofstream对象提供文件名作为初始化式,就相当于打开了特定的文件

1
2
ifstream infile; //unbound input file stream
ofstream outfile; //unbound output file stream

上述语句将infile定义为读文件的流对象,将outfile定义为写文件的对象。这两个对象都没有捆绑具体的文件。在使用fstream对象之前,还必须使这些对象捆绑要读写的文件:

1
2
infile.open(“in”); //open file named “in” in the current directory
outfile.open(“out”) //open file named “out” in the current directory

调用open成员函数将已经存在的fstream对象与特定的文件绑定。为了实现读写,需要将指定的文件打开并定位,open函数完成系统指定的所有需要的操作,总之绑定的方式有两种一种是直接使用ifile.c_str()类型的参数,另一种是调用open成员函数。

补充:C++中的文件名
由于历史原因,IO标准库使用C风格字符串而不是C++ string类型的字符串作为文件名。在创建fstream对象时,如果调用open或使用文件名作为初始化式,需要传递的实参应为C风格字符串,而不是标准库string对象。程序常常从标准输入获得文件名。通常,比较好的方法是将文件名读入string对象,而不是C风格字符数组。假设要使用的文件名保存在string对象中,则可调用c_str()成员获取C风格字符串。

我在CSDN上求助的解答:点击这里