服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++IO流之fstream, stringstream使用小结

C++IO流之fstream, stringstream使用小结

2022-11-08 12:42AKA你的闺蜜 C/C++

C语言中常用的输入输出函数有如下几种:前者是格式化标准输入输出,后者是格式化文件输入输出,最后是格式化字符串输入输出,这篇文章主要介绍了C++IO流:fstream, stringstream总结,需要的朋友可以参考下

IO流

1. C语言IO

C语言中常用的输入输出函数有如下几种:前者是格式化标准输入输出,后者是格式化文件输入输出,最后是格式化字符串输入输出。

函数名 内容 备注
scanf 标准输入流(键盘)读取格式化的数据 省略standard
fscanf 所有输入流读取读取格式化数据 f:file
sscanf 字符串中读取格式化的数据 s:string
printf 将格式化的数据输出到标准输出流(屏幕)上 省略standard
fprintf 将格式化数据输出到所有输出流 f:file
sprintf 将格式化的数据输出到字符串 s:string

文件的输入输出需要以下几个函数:

函数名 功能 适用范围
fopen 打开文件流 文件
fclose 关闭文件流 文件
fscanf 所有输入流读取读取格式化数据 文件
fprintf 将格式化数据输出到所有输出流 文件
fread 二进制输入 文件
fwrite 二进制输出 文件
?
1
2
3
4
5
6
7
8
9
//文件开关
FILE* fopen   (const char* filename, const char* mode);
int   fclose  (FILE* stream);
//格式化读写
int fprintf (FILE* stream, const char* format [, argument ]...);
int fscanf  (FILE* stream, const char* format [, argument ]...);
//二进制读写
size_t fwrite  (const void* buffer, size_t size, size_t count, FILE* stream);
size_t fread   (      void* buffer, size_t size, size_t count, FILE* stream);

使用方式如下:

?
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
struct ServerInfo
{
    char _ip[32];
    int _port;
    friend ostream& operator<<(ostream& os, ServerInfo& info);
    friend ostream& operator>>(ostream& os, ServerInfo& info);
};
//测试C语言二进制读写
void TestC_Write_Bin() {
    ServerInfo info = { "192.168.1.1",80 };
    FILE* fout = fopen("info.bin", "wb");
    //assert();
    fwrite(&info, sizeof(ServerInfo), 1, fout);
    fclose(fout);
}
void TestC_Read_Bin() {
    ServerInfo info;
    FILE* fin = fopen("info.bin", "rb");
    fread(&info, sizeof(ServerInfo), 1, fin);
    printf("%s:%d", info._ip, info._port);
    fclose(fin);
}
//测试C语言字符读写
void TestC_Write_Text() {
    ServerInfo info = { "192.168.1.1",80 };
    FILE* fout = fopen("info.txt", "w");
    fprintf(fout, "%s %d", info._ip, info._port);
    fclose(fout);
}
void TestC_Read_Text() {
    ServerInfo info;
    FILE* fin = fopen("info.txt", "r");
    fscanf(fin, "%s %d", &info._ip, &info._port);
    printf("%s:%d", info._ip, info._port);
}

2. C++IO

C++IO流之fstream, stringstream使用小结

C++ 标准库提供了4个全局流对象cincoutcerrclog。cout、cerr、clog 是 ostream 类的三个不同的对象。使用 cout 进行标准输出,使用 cin 进行标准输入。同时 C++ 标准库还提供了 cerr 用来进行标准错误的输出,以及 clog 进行日志的输出。

2.1 C++标准IO流

cout,cinostream,istream类的对象,operator<<,operator>>分别是两个对象的操作符重载成员函数。

C++IO流之fstream, stringstream使用小结

C++输出输入可直接使用cout>>cin>>,因为其重载了所有内置类型,对于自定义类型需要自行重载操作符>><<

?
1
cin >> a >> b;

operator<<operator>>的返回值也是ostream&istream&,因此支持连续输入输出,又是一次函数调用。

cout/cin 取代 printf/scanf 的真正原因是 cout/cin 支持自定义类型,符合面向对象的思想。

当需要循环读入数据时,可以采用如下的方式:

?
1
2
3
4
string str;
while (cin >> str) {
    ;
}

从文档中可以看到,operator>>的返回值是istream类型,这个对象类型是如何作真假判断的呢?

原因是istream类的对象支持一个操作符的重载函数叫operator bool,C++98中叫operator void*,C++11中叫operator bool

C++IO流之fstream, stringstream使用小结

这是个特殊的运算符重载函数,该函数不允许限定返回类型,当类型被当作条件判断时,自动调用并将返回值强转为内置的标识,该标识如果为真就继续,如果为假就停止读取。

2.2 C++文件IO流

采用面向对象的思想,C++中文件指针被文件输入输出流对象ofstreamifstream代替。

fopen的调用方式类似,创建输入输出流对象,调用其构造函数传入文件地址以及打开模式。fclose被析构函数代替,且析构函数可以自动调用。

对象构造函数 解释
ofstream (const char fileName, ios_base::openmode mode=ios_base::out)* 创建输出流对象,并指定文件地址和打开模式
ifstream (const char fileName, ios_base::openmode mode=ios_base::in)* 创建输入流对象,并指定文件地址

打开模式变量的类型是ios_base::openmode,该变量有如下几个特定的值:

模式 解释
in 文件读取模式
out 文件写入模式
binary 二进制文件模式
 

常用的有如上几种,该变量的值以二进制位中的不同位为1来标识,也就是说使用异或|就可以组合起来用。

函数 解释
istream& read(char s, streamsize n);* read接口是输入流istream对象的成员函数,参数是变量和大小。
ostream& write(const char s , streamsize n);* write接口是输出流ostream对象的成员函数,参数是写入变量和写入大小。

示例

使用一个ConfigManage类来演示几种文件读写的方式。

?
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
struct ServerInfo
{
    char _ip[32];
    int _port;
    friend ostream& operator<<(ostream& os, ServerInfo& info);
    friend ostream& operator>>(ostream& os, ServerInfo& info);
};
class ConfigManage {
public:
    ConfigManage(const char* fileName)
        :_fileName(fileName)
    {}
    //二进制写入
    void WriteBin(ServerInfo& info)
    {
        ofstream ofs(_fileName.c_str(), ios_base::out | ios_base::binary); //创建输出流对象
        ofs.write((const char*)&info, sizeof(ServerInfo)); //调用write接口
    }
    //二进制读取
    void ReadBin(ServerInfo& info)
    {
        ifstream ifs(_fileName.c_str(), ios_base::in | ios_base::binary);
        ifs.read((char*)&info, sizeof(ServerInfo));
        cout << info << endl;
    }
private:
    string _fileName;
};

读写文件更常用的方式是以文本形式读写,因此就可以省略打开模式参数。

ifstream,ofstream文件输入输出类中还继承了iostream的流插入<<流提取>>操作符,也就是对象ofsifs也可以使用<<>>操作符。

?
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
struct ServerInfo {
    friend ostream& operator<<(ostream& os, ServerInfo& info);
    friend ostream& operator>>(ostream& os, ServerInfo& info);
    char _ip[32];
    int _port;
};
ostream& operator<<(ostream& os, ServerInfo& info) {
    os << info._ip << " " << info._port;
    return os;
}
istream& operator>>(istream& is, ServerInfo& info) {
    is >> info._ip >> info._port;
    return is;
}
//文本写入
void WriteText(ServerInfo& info)
{
    ofstream ofs(_fileName.c_str());
    //write
    ofs.write((const char*)&info, sizeof(ServerInfo));
    //1.
    ofs << info._ip << info._port; //对象未重载<<
    //2.
    ofs << info; //对象已重载>>
}
//文本读取
void ReadText(ServerInfo& info)
{
    ifstream ifs(_fileName.c_str());
    //read
    ifs.read((char*)&info, sizeof(ServerInfo));
    //1.
    ofs << info._ip << info._port; //对象未重载<<
    //2.
    ifs >> info; //对象已重载>>
    cout << info << endl;
}

具体调用方式则是如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void TestCPP_Write_Bin() {
    ServerInfo info = { "192.168.1.1",80 };
    ConfigManage con("config.bin");
    con.WriteBin(info);
}
void TestCPP_Read_Bin() {
    ServerInfo info;
    ConfigManage con("config.bin");
    con.ReadBin(info);
}
void TestCPP_Write_Text() {
    ServerInfo info = { "192.168.1.1",80 };
    ConfigManage con("config.bin");
    con.WriteText(info);
}
void TestCPP_Read_Text() {
    ServerInfo info;
    ConfigManage con("config.bin");
    con.ReadText(info);
}

文件的输入输出流对象调用构造函数时也可能会失败,C++采取面向对象抛异常的形式。

2.3 C++ stringstream

在头文件 下,有三个类:istringstream、ostringstream 和 stringstream,分别用来进行字符串流的输入、输出和输入输出操作。

  • 字符串流ostringstream可以将一个其他类型的数据转化为字符串格式,该类中的成员函数str可以返回转出的字符串。
  • 字符串流istringstream可以将一个字符串格式转化其他类型的数据,该类中的成员函数str可以传入需要转化的字符串,或直接在构造时传入。
?
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
struct PersonInfo
{
    string _name;
    int _age;
    friend ostream& operator<<(ostream& os, PersonInfo& info);
    friend istream& operator>>(istream& is, PersonInfo& info);
};
//序列化
PersonInfo info1 = { string("zhangsan"), 20 };
ostringstream oss;
//1.
oss << info1._name << " " << info1._age; //对象未重载<<
//2.
oss << info1;
string str = oss.str();
cout << str << endl;
 
//反序列化
PersonInfo info2;
istringstream iss(str);
iss.str(str);
//1.
iss >> info2._name >> info2._age; //对象未重载>>
//2.
iss >> info2;
cout << info2 << endl;

到此这篇关于C++IO流:fstream, stringstream总结的文章就介绍到这了,更多相关C++ fstream, stringstream内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/yourfriendyo/article/details/124061797

延伸 · 阅读

精彩推荐
  • C/C++C++求解二叉树的下一个结点问题

    C++求解二叉树的下一个结点问题

    本文将通过C++求解以下问题:给定一个二叉树其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。文中示例代码讲解详细,感兴趣的可以了解一...

    翟天保Steven10992022-11-03
  • C/C++深入了解C++中map用法

    深入了解C++中map用法

    下面小编就为大家带来一篇深入了解C++中map用法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随想过来看看吧...

    C++教程网10022021-04-08
  • C/C++详解C++中虚析构函数的作用及其原理分析

    详解C++中虚析构函数的作用及其原理分析

    这篇文章主要介绍了C++中虚析构函数的作用及其原理分析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋...

    Stoneplay266942021-07-27
  • C/C++C++基于递归算法解决汉诺塔问题与树的遍历功能示例

    C++基于递归算法解决汉诺塔问题与树的遍历功能示例

    这篇文章主要介绍了C++基于递归算法解决汉诺塔问题与树的遍历功能,简单描述了递归算法的原理,并结合实例形式分析了基于递归算法解决汉诺塔问题与数...

    侯凯4952021-06-09
  • C/C++C++ 实现哈希表的实例

    C++ 实现哈希表的实例

    这篇文章主要介绍了C++ 实现哈希表的实例的相关资料,这里使用C++实现哈希表的实例帮助大家彻底理解哈希表的原理,需要的朋友可以参考下...

    liuzhanchen198710762021-05-31
  • C/C++关于c语言逗号表达式的运算规则知识点

    关于c语言逗号表达式的运算规则知识点

    在本篇文章里小编给大家整理的是关于c语言逗号表达式的运算规则知识点,需要的朋友们可以学习参考下。...

    angryTom12362021-08-20
  • C/C++纯C语言:贪心Prim算法生成树问题源码分享

    纯C语言:贪心Prim算法生成树问题源码分享

    这篇文章主要介绍了贪心Prim算法生成树问题源码,有需要的朋友可以参考一下...

    C语言教程网6012021-01-13
  • C/C++c++实现俄罗斯方块游戏代码

    c++实现俄罗斯方块游戏代码

    大家好,本篇文章主要讲的是c++实现俄罗斯方块游戏代码,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下...

    m0_5159216911292022-08-08