作者:@小萌新
专栏:@C++初阶
作者简介:大二学生 希望能和大家一起进步!
本篇博客简介:简单介绍C++中的文件操作和io流
文件操作和io流
- C语言中的输入和输出
- 流是什么?
- C++io流
- C++标准io流
- C++中流的特性
- C++文件io流
- 以二进制形式操作文件
- 以文本形式操作文件
- 以流形式操作文件
- stringstream的介绍
- 总结
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++中操作一个文件流对象有下面几步
-
定义一个文件流对象
-
使用文件流对象以一种方式打开一个磁盘文件
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类