在程序设计中,数据输入/输出(I/O)操作是必不可少的,C++语言的数据输入/输出操作是通过I/O流库来实现的。C++中把数据之间的传输操作称为流,流既可以表示数据从内存传送到某个载体或设备中,即输出流,也可以表示数据从某个载体或设备传送到内存缓冲区变量中,即输入流。
C++流涉及以下概念:
标准I/O流:内存与标准输入输出设备之间信息的传递;文件I/O流:内存与外部文件之间信息的传递;字符串I/O流:内存变量与表示字符串流的字符数组之间信息的传递。
STL中定义的流类:
流类分类 |
流类名称 |
流 类 作 用 |
流基类 |
ios |
所有流类的父类,保存流的状态并处理错误 |
输入流类 |
istream |
输入流基类,将流缓冲区中的数据作格式化和非格式化之间的转换并输入 |
|
ifstream |
文件输入流类 |
|
istream_withassign |
cin输入流类,即操作符>>输入流 |
|
istrstream |
串输入流类, 基于C类型字符串char*编写 |
|
istringstream |
串输入流类, 基于std::string编写 |
输出流类 |
ostream |
输出流基类,将流缓冲区中的数据作格式化和非格式化之间的转换。并输出 |
|
ofstream |
文件输出流类 |
|
ostream_withassign |
Cout、cerr、clog的输出流类,即操作符<<输出流 |
|
ostrstream |
串输入流类, 基于C类型字符串char*编写 |
|
ostringstream |
串输入流类, 基于std::string编写 |
输入/输出流类 |
iostream |
多目的输入/输出流类的基类 |
|
fstream |
文件流输入/输出类 |
|
strstream |
串流输入/输出类, 基于C类型字符串char*编写 |
|
stringstream |
串流输入/输出类, 基于std::string编写 |
注,对于串流,提供了两套类,一个基于C类型字符串char *编写(定义于头文件strstream),一个基于std::string编写(定义于sstream), 后者是C++标准委员会推荐使用的。另外看一些资料,都说还定义了文件流和串流的基类fstreambase和strstreambase,而且描述ofstream继承于ostream和fstreambase,但没有找到,于是省略了。可搜索关键字(fstreambase或strstreambase)查看详情。
预定义标准流对象:
istream &cin; //键盘
ostream &cout; //屏幕
ostream &cerr; //屏幕
ostream &clog; //打印机
wistream &wcin;
wostream &wcout;
wostream &wcerr;
wostream &wclog;
C++中读取string对象
1.标准输入读取:cin >> string
a.忽略开头所有的空白字符(空格、换行、制表符等);
b.读取字符直至再次遇到空白字符,读取终止;
2.读取整行文本:getline(istream, string)
a.不忽略开头的空白字符;
b.读取字符直至遇到换行符,如果第一个字符是换行符,则返回空string;
c.返回时丢弃换行符,换行符不存储在string中。
STL C++中string、ifstream、stringstream的使用
1、从标准输入接受字符串,然后进行相关处理
#include
#include
#include
using namespace std;
int main()
{
string s; //定义一个stirng对象,从标准输入接受一个字符串
cout<<"请输入一行字符串:"<
getline(cin,s);
stringstream ss(s); //定义一个string流(使用s实例化)
cout<<"处理后的字符串为:"<
for(string s1;ss>>s1;cout<
return 0;
}
运行结果如下:
请输入一行字符串:
you are a good boy
处理后的字符串为:
you
are
a
good
boy
根据前文所说“忽略开头空白字符,读取字符直至再次遇到空白字符为止”,这样的结果不难理解。
2、从文件读入字符串,然后进行相关处理
#include
#include
#include
#include
using namespace std;
int main()
{
ifstream fin("test.in"); //定义一个文件输入流,从文件中读取数据
if(!fin)
{
cout<<"can not open the input file";
return -1;
}
string s; //定义一个string,获取文件输入流中的一行
while(getline(fin,s))
{
stringstream ss(s); //定义一个string流(使用一个string对象填充)
int a,b;
ss>>a;ss>>b; //将string流中的两个值分别读入a、b中
cout<<"该行数据和为:"<
}
return 0;
}
test.in文件内容如下:
1 10
2 100
3 8
4 9
运行结果为:
该行数据和为:11
该行数据和为:102
该行数据和为:11
该行数据和为:13
其中,getline函数原型如下:
template
basic_istream
&
getline(
basic_istream
& is,
basic_string
& str);
template
basic_istream
&
getline(
basic_istream
& is,
basic_string
& str,
E delim);
第二个重载函数很有意思,结尾是char, 或wchar型的一个分隔符,如果设为’\n’,则为以换行符为分隔,如果设为’,',则为以逗号为分隔。由此,虽然C++中的字符串没有分割函数,如果是从文件中读取出被特定分隔符分隔的文本,那么就可以用此方法,如:
std::ifstream file;
file.open("tt.txt");
std::string s,t;
while(std::getline(file,s)) //按行读取
{
std::stringstream strs(s); //把行装到另一个流中
while(std::getline(strs,t,’,')) //把流按分隔符实现分割
std::cout<
}
file.close();
上面的程序相当于将整个文本先按行分割,再按分隔符分割,也可以变换一下,只按分隔符分割,然后过滤掉按行符,换行符与某元素连在了一起,并处于开头。
C++的流操作复制文件
写.wrl, .obj文件格式转换时用到,记录一下相关方法
使用C++标准程序库的输入输出流(I/O Stream)复制文件,存在许多的方法,
方法一:逐个字符复制
#include < fstream >
std::ifstream input("in",iOS::binary);
std::ofstream output("out",ios::binary);
char ch;
while (input.get(ch)) output << ch;
注意:如果使用input>>ch读取字符,则必须先调用input.unsetf(ios