C++语言的输入输出机制包含3层,前两层是从传统的C语言继承而来,分别是底层I/O和高层I/O,第3层是C++中增添的流类库,重点。
(1)底层I/O:底层I/O依赖于操作系统来实现,调用操作系统的功能对文件进行输入输出处理,具有较高的速度。底层I/O将外部设备和磁盘文件都等同于逻辑文件,采用相同的方法进行处理,一般过程为“打开文件”、“读写文件”,“关闭文件”,这些是通过一组底层I/O函数来完成的,这些函数定义在头文件io.h中2016/11/8 12:13:19。
(3)流类库:除了从C语言中继承了上述两种I/O机制外,C++还特有一种输出机制:流类库(即iostream类库),这是C++所特有的,iostream类库为内置类型对象提供了输入输出支持,也支持文件的输入输出,另外,类的设计者可以通过运算符重载机制对iostream库的扩展,来支持自定义类型的输入输出操作。
// iostream 继承层次
---------------------------------------------------------------------------------------
流的分类:
1. 标准输入输出流 -- 头文件<iostream>
cin/cout/cerr-- printf/scanf
2.文件输入输出流 -- 头文件<fstream>
ifstream/ofstream/fstream
fprintf fscanf
3. 字符串流 -- 头文件<sstream>
istringstream/ostringstream/stringstream
sscanf sprintf
---------------------------------------------------------------------------------------
标准输入输出流:
流的状态:
badbit 系统级故障,不可恢复
failbit 可以恢复的错误
eofbit 碰到了文件结尾
goodbit 有效状态
查询流的状态:
cin.bad()
cin.fail()
cin.eof()
cin.good()
重置状态 cin.clear()
#include<iostream>
#include<string>
#include<limits>
using namespace std;
void print_cin()
{
cout<<"badbit="<<cin.bad()<<endl;
cout<<"failbit="<<cin.fail()<<endl;
cout<<"eofbit="<<cin.eof()<<endl;
cout<<"goodbit="<<cin.good()<<endl;
}
int main()
{
print_cin();
cout<<endl;
int num;
while(cin>>num)
cout<<"num="<<num<<endl;
print_cin();
cout<<endl;
cin.clear();
print_cin();
cout<<endl;
//cin.ignore(numeric_limits<streamsize>::max(),'\n');
//不加这句话,下面语句就会把刚才错误输入的字符串直接输出来
cin.ignore(1024,'\n');
//同上,表示最多忽略1024个字符,期间遇到'\n'就开始执行下面语句
string s;
cin>>s;
cout<<s<<endl;
return 0;
}
|
#include<iostream>
#include<limits>
using namespace std;
int main()
{
int num;
while(cin>>num,!cin.eof())
{
if(cin.good())
{
cout<<"num="<<num<<endl;
}
if(cin.fail())
{
cout<<"data error,try again"<<endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
//cin.clear(); 会出现死循环,必须在ignore前面使用
}
}
return 0;
}
|
//设置忽略3个字符 //没加ignore //正常预期效果
----------------------------------------------------------------------------------------------------------------------------
文件输入输出流 <fstream>
ifstream 文件输入流
ofstream 文件输出流
fstream 二者兼有
#include<iostream>
#include<string>
#include<fstream>
#include<vector>
using namespace std;
int main()
{
ifstream in("file");
if(!in.good())
{
cout<<"open file fail!"<<endl;
return -1;
}
vector<string> vec;
vec.reserve(10);
string str;
while(getline(in,str))
cout<<str<<endl;
// vec.push_back(str);
cout<<endl;
in.close();
return 0;
}
|
使用迭代器
vector<string>::iterator p;
#if 1
for(p=vec.begin();p!=vec.end();p++)
{
cout<<*p<<endl;
}
#endif
|
#include <iostream>
#include<string>
#include<fstream>
using namespace std;
int main()
{
ifstream in("file"); //要求文件事先存在
if(!in.good())
{
cout<<"open file fail!"<<endl;
return -1;
}
ofstream out("file1"); //对文件存不存在没有要求
if(!out.good())
{
cout<<"open file1 fail!"<<endl;
return -1;
}
string str;
while(getline(in,str))
{
out<<str<<endl;
}
in.close();
out.close();
return 0;
}
|
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
fstream io("file") ; //要求文件事先存在
if(!io.good())
{
cout<<"open file fail!"<<endl;
return 0;
}
int num;
for(int i=0;i!=10;i++)
{
cin>>num;
io<<num<<" ";
}
io<<endl;
cout<<endl;
cout<<"io.tellp()="<<io.tellp()<<endl<<endl; //tellp()ifstream对象特有
io.seekp(0,ios::beg);
for(int i=0;i<10;i++)
{
io>>num;
cout<<num<<" ";
}
cout<<endl<<endl;
cout<<"io.tellg()="<<io.tellg()<<endl; //tellg(),ofstream对象特有
return 0;
}
|
文件模式
ios::in 打开文件做读操作
ios::out 打开文件做写操作,会删除原有数据
ios::app 在每次写之前找到文件尾 //只对输出流起作用<<
ios::trunc 打开文件时清空已存在的文件流
ios::ate 打开文件后立即定位到文件末尾 //只对输入流起作用>>
ios::binary 以二进制模式进行IO操作
ios::beg 文件流指针定位到文件开头
字符串输入输出流 <sstream>
//把非字符串的数据转换成字符串时就使用它类似sprintf(); //字符串拼接
istringstream
ostringstream
stringstream
#include <iostream>
#include<sstream>
#include<string>
#include<stdio.h>
#include<string.h>
using namespace std;
void sprint(int a,int b)
{
char arr[100];
memset(arr,0,sizeof(arr));
sprintf(arr,"%d,%d",a,b);
cout<<arr<<endl;
}
string ostring(int a,int b) //这里字符串,整形都可以
{
ostringstream oss;
//stringstream oss; //一样的效果
oss<<a<<","<<b;
}
void istring(string line)
{
istringstream iss(line);
//stringstream iss(line);
string world;
while(iss>>world)
{
cout<<world<<endl;
}
}
|
int main()
{
int a=512;
int b=1024;
sprint(a,b);
cout<<endl;
string s = ostring(a,b);
cout<<s<<endl<<endl;
string s1 = "hello world shen zhen";
istring(s1);
return 0;
}
|
3. 统计一篇英文(The_Holy_Bible.txt)文章中出现的单词和词频,
输入:某篇文章的绝对路径
输出:词典(词典中的内容为每一行都是一个“单词 词频”)
-----------------
| a 66 |
| abandon 77 |
| public 88 |
| ...... |
|_________________|
class WordStatic
{
public:
void read_file(std::string filename);
void write_file(std::string filename);
private:
//......
};
|
#include <iostream>
#include<fstream>
#include<vector>
#include<string>
#include<string.h>
#include<iomanip>
using namespace std;
class WordStatistic
{
private:
vector<string> word;
vector<int> count;
public:
void read_file(string filename);
void write_file(string filename);
};
void WordStatistic::read_file(string filename)
{
char name[100]; //这里不能定义指针,不然段错误
strcpy(name,filename.c_str());
ifstream in(name);
//括号里面的参数必须是const char*
if(!in.good())
{
cout<<"open file fail!"<<endl;
return ;
}
cout<<"正在统计文件……"<<endl;
string tmpword;
while(in>>tmpword)
{
if(tmpword[0]>='0'&&tmpword[0]<='9')
continue;
int vecwordsize=word.size();
int i;
for(i=0;i<vecwordsize;i++)
{
if(word[i].compare(tmpword)==0)
//if(vers[idx]==tmpword)
{
count[i]++;
break;
}
}
if(i==vecwordsize)
{
word.push_back(tmpword);
count.push_back(1);
}
}
in.close();
cout<<"统计结束!"<<endl;
}
|
void WordStatistic::write_file(string filename)
{
char name[100];
strcpy(name,filename.c_str());
ofstream out(name);
cout<<"统计结果正在写入文件……"<<endl;
if(out.good()==0)
{
cout<<"open outfile fail!"<<endl;
return ;
}
for(int i=0;i<word.size();i++)
{
out<<setw(20)<<word[i]<<setw(15)<<count[i]<<endl;
}
out.close();
cout<<"写入结束!"<<endl;
}
int main()
{
WordStatistic WS;
WS.read_file("The_Holy_Bible.txt");
WS.write_file("统计结果.txt");
return 0;
}
|
一共12567个单词