C语言中的输入和输出
首先我们先回顾下在C语言中我们是怎么样输入和输出的
经常使用的两个函数是不是printf还有scanf
关于printf的具体介绍和用法可以参考我的这篇博客
Printf的使用
我们使用printf输出 使用sacnf输入来完成C语言中的各种io操作
流是什么?
“流”即是流动的意思,是物质从一处向另一处流动的过程,是对一种有序连续且有方向性的数据的抽象描述。
所以从这段文字中我们就能推断出流的特性
它具有有序性 连续性 方向性
比如说我们的cout 就叫做流插入操作符 它用来输出数据
它可以连续的输出数据 它输出数据是有序的 全部符合流的性质
cin 流提取操作符同理
为了实现这种流动 C++定义了I/O标准类库 当中的每个类都称为流/流类 用以完成某方面的功能
C++io流
如下图
C++标准io流
C++标准库提供了4个全局流对象(cin、cout、cerr、clog):
使用cout进行标准输出,即数据从内存流向控制台(显示器)。
使用cin进行标准输入,即数据通过键盘输入到程序中。
使用cerr进行标准错误的输出。
使用clog进行日志的输出。
我们很明显可以发现 1 3 4全部是输出流 而2是输入流
C++中流的特性
流从缓冲区中读取数据 缓冲区数据读取完毕之后才会要求输入新的数据
以下面的代码为例
这里我们可以发现 其实我们只输入了一行的数据 就覆盖了 a b
输入的数据必须要类型正确
我们可以发现 输入了两个错误格式的数据 b并没有被赋值
如果要读取一整行的数据 我们只能用getline
假设我们要输入一个字符串 hello world
由于cin读取到空格便会结束 所以说我们没办法完整的输入之
这个时候就要用到我们的getline函数了
cout 和 cin 之所以能够识别不同类型的数据 是因为 它们进行了运算符重载
自定义类型的输入和输出 一般要我们来自己来重载
比如说下面的日期类
class Date { public: friend ostream& operator << (ostream& out, Date& d); Date() :_year(2022), _month(12), _day(18) { ; } private: int _year; int _month; int _day; }; ostream& operator<<(ostream& out, Date& d) { out << d._year << " " << d._month << " " << d._day; return out; }
在线oj题中的输出
我们使用如下格式的代码 来重复输入 输出
值得一提的是 我们可以使用ctrl + z来模拟文件结束的标志
C++文件io流
C++中操作一个文件流对象有下面几步
1 定义一个文件流对象
2 使用文件流对象以一种方式打开一个磁盘文件
3. 使用流插入和流提取运算符对文件进行操作
4. 关闭文件
以二进制形式操作文件
我们直接来看代码
void test1() { fstream ofile; // 定义一个文件流对象 ofile.open("test.bin", ostream::out | ostream::binary); //我们这里使用或来表示同时进行的意思 char arr[] = "hello world"; ofile.write(arr, strlen(arr)); ofile.put('!'); ofile.close(); }
当我们写完这个程序的时候就已经在我们的磁盘中写好了 hello world!的二进制文件
接下来我们试试看读取文件
void test2() { ifstream ifile; ifile.open("test.bin", ofstream::in | ofstream::binary); ifile.seekg(0, ifile.end); //跳转到文件末尾 int length = ifile.tellg(); //获取当前字符在文件当中的位置,即文件的字符总数 ifile.seekg(0, ifile.beg); //重新回到文件开头 char arr[100] = ""; ifile.read(arr, length); cout << arr << endl; ifile.close(); }
最后我们看看效果
以文本形式操作文件
文本形式相对于二进制形式操作 实际上就少了一个声明二进制的读写方式
void test3() { fstream ofile; // 定义一个文件流对象 ofile.open("test1.txt",ofstream::out); char arr[] = "hello world"; ofile.write(arr, strlen(arr)); ofile.put('!'); ofile.close(); }
void test4() { ifstream ifile; ifile.open("test1.txt"); ifile.seekg(0, ifile.end); //跳转到文件末尾 int length = ifile.tellg(); //获取当前字符在文件当中的位置,即文件的字符总数 ifile.seekg(0, ifile.beg); //重新回到文件开头 char arr[100] = ""; ifile.read(arr, length); cout << arr << endl; ifile.close(); }
注意: 使用ofstream类对象的open函数时,若不指定打开方式,则默认以写的方式打开文件;使用ifstream类对象的open函数时,若不指定打开方式,则默认以读的方式打开文件;使用fstream类对象的open函数时,若不指定打开方式,则默认以写+读的方式打开文件
以流形式操作文件
插入
void test5() { ofstream ofs("mh.txt"); ofs << "helloworld"; ofs.close(); }
提取
void test6() { ifstream ifs("mh.txt"); char arr[100] = ""; ifs >> arr; ifs.close(); cout << arr << endl; }
stringstream的介绍
如果我们要想将一个整型数据转化为字符串格式 有下面的两种方式
1、使用itoa函数进行转化。
int a = 10; char arr[10]; itoa(a, arr, 10); //将整型的a转化为十进制字符数字存储在字符串arr当中
2、使用sprintf函数进行转化。
int a = 10; char arr[10]; sprintf(arr, "%d", a); //将整型的a转化为字符串格式存储在字符串arr当中
而在C++中我们则有一种新的方式
stringstream
它的两种用法分别是
1 将数值类型的数据转化为字符串类型
void test7() { string s1; stringstream s; int a = 10; s << a; s >> s1; cout << s1; }
2. 拼接字符串 例如
void test8() { string s1; stringstream s; s << "hello " << "world!"; s1 = s.str(); cout << s1; }
总结
本篇博主主要介绍了C++中的文件操作和io流 还有一个简单的stringstream类