在C语言中,我们经常用到的输入和输出的函数共有三组
输入/输出 | 操作对象 |
---|---|
printf/scanf | 控制台 |
fprintf/fscanf | 文件 |
sprintf/sscanf | 字符数组(缓冲区) |
而C++中对应的操作如下
输入/输出 | 操作对象 |
---|---|
ostream/isream | 控制台 |
ofstream/istream | 文件 |
ostringstream/istringstream | 字符数组(缓冲区) |
流即流动的意思,是物质从一处向另一处流动的过程,是对一种有序连续且具有方向性的数据的抽象描述 C++流是指信息从外部输入设备(比如键盘)向计算机内部(内存)输入和从内存向外部输出设备(比如屏幕)的过程
为了实现这种流动,C++定义了I/O标准类库,每个类称为一个流,以完成某些功能。
C++实现了一个庞大的类库,其中IOS为基类,其他类都是直接或间接派生自IOS类
我们进城使用的cin和cout就是该类的一个对象
**C++标准库提供了4个全局流对象:cin
,cout
,cerr
,cblog
。分别对应标准输入,标准输出,标准错误和标准日志 **
对于cin
要特别注意以下几点
cin
输入,字符串中不能有空格,但是可以使用getline(cin,"this is a test")
//单个元素输入
while(cin>>a)
{
//代码片段
}
//多个元素循环输入
while(cin>>a>>b>>c)
{
//代码片段
}
//整行接受
while(cin>>str)
{
//代码片段
}
C/C++根据文件内容的数据格式分为二进制文件和文本文件
在C语言中读写文件其实是一个相对比较繁琐的操作,因为有很多参数需要记忆,而且还要打开文件关闭文件。但是在C++中,我们使用的仍然是面向对象的思想。
我们主要会使用到两种文件流:
ifstream ifile
(只做输入)ofstream ofile
(只做输出)实例化后对象之后,文件操作就变成了调用这些对象的接口的操作了。
如下,我们用一个服务器的ip及端口号信息进行演示,它封装在一个结构体SeverInfo
中
struct ServerInfo
{
char _ip[32];//Ip地址
int _port;//端口号
};
我们创建一个类ConfigManager,这个类所做的工作就是将数据写入到文件,或者文件读取内存等操作
首先是类的成员,类里面的成员就定义一个string
,这个string
存放的是到时候要将数据写入到磁盘上的文件名,这里我定义为myconfig.txt
class ConfigManager
{
public:
ConfigManager(const char* configfile = "myconfig.txt")//构造
:_configfile(configfile)
{
}
private:
string _configfile;//配置文件名字
};
首先进行的是打开文件以二进制的方式写入结构体的内容,需要使用到的流是ofstream
,其构造函数是
explicit ofstream (const char* filename, ios_base::openmode mode = ios_base::out);
ofstream
对象的write
方法的参数为
ostream& write (const char* s, streamsize n);
char*
接着是使用二进制的方式打开读入,需要使用的流是ifstream
和read
方法
所以二进制的读写如下
void WriteBin(const ServerInfo& info)
{
ofstream ofs(_configfile);//二进制写入对象
ofs.write((const char*)& info, sizeof(ServerInfo));//写入
}
void ReadBin(const ServerInfo& info)
{
ifstream ifs(_configfile);//二级制从某文件读取
ifs.read((char*)& info, sizeof(ServerInfo));//读入
}
int main()
{
ConfigManager conf;
ServerInfo W_info;
ServerInfo R_info;
strcpy(W_info._ip, "198.168.0.1");
W_info._port = 22;
conf.WriteBin(W_info);//二进制写入到磁盘
conf.ReadBin(R_info);//然后读取的R_info中
cout << R_info._ip << endl;
cout << R_info._port << endl;
}
然后,对于文本读写在C++则是非常简单,因为ofstream
和ifstream
都分别重载了<<
和>>
运算符
void WriteText(const ServerInfo& info)//文本方式写入
{
ofstream ofs(_configfile);
ofs << info._ip << endl;
ofs << info._port << endl;//注意加入换行符,不然分不清楚
}
void ReadText(ServerInfo& info)
{
ifstream ifs(_configfile);
ifs >> info._ip;
ifs >> info._port;
}
int main()
{
ConfigManager conf;
ServerInfo W_info;
ServerInfo R_info;
strcpy(W_info._ip, "198.168.0.1");
W_info._port = 22;
conf.WriteText(W_info);
conf.ReadText(R_info);
cout << R_info._ip << endl;
cout << R_info._port << endl;
}
定义了三个类,分别为istringstream
,ostringstream
和stringstream
。其中最为重要的就是stringstream
#include
#include
#include
#include
using namespace std;
int main()
{
stringstream sstream;
string strResult;
int nValue = 1000;
// 将int类型的值放入输入流中
sstream << nValue;
// 从sstream中抽取前面插入的int类型的值,赋给string类型
sstream >> strResult;
cout << "[cout]strResult is: " << strResult << endl;
printf("[printf]strResult is: %s\n", strResult.c_str());
return 0;
}
.str()
方法是将stringstream
类型转换为string
#include
#include
#include
using namespace std;
int main()
{
stringstream sstream;
// 将多个字符串放入 sstream 中
sstream << "first" << " " << "string,";
sstream << " second string";
cout << "strResult is: " << sstream.str() << endl;
// 清空 sstream
sstream.str("");
sstream << "third string";
cout << "After clear, strResult is: " << sstream.str() << endl;
return 0;
}
str("")
和clear()
的区别:clear()不会清空内容,他只是把最初对字符串转换类型等操作清除而已,相当于“初始化”。如果转换成int,那么就不能把向原字符串添加内容了,这时候可以使用clear(),str()只是把内容变成“”,而且也没有办法向里面添加内容了,后面跟一个clear()的话就可以添加内容了