C++ 初阶 文件操作和io流

简介: C++ 初阶 文件操作和io流

C语言中的输入和输出


首先我们先回顾下在C语言中我们是怎么样输入和输出的


经常使用的两个函数是不是printf还有scanf


关于printf的具体介绍和用法可以参考我的这篇博客


Printf的使用


我们使用printf输出 使用sacnf输入来完成C语言中的各种io操作


流是什么?

“流”即是流动的意思,是物质从一处向另一处流动的过程,是对一种有序连续且有方向性的数据的抽象描述。


所以从这段文字中我们就能推断出流的特性


它具有有序性 连续性 方向性


比如说我们的cout 就叫做流插入操作符 它用来输出数据


它可以连续的输出数据 它输出数据是有序的 全部符合流的性质


cin 流提取操作符同理


为了实现这种流动 C++定义了I/O标准类库 当中的每个类都称为流/流类 用以完成某方面的功能


C++io流


如下图


809d23c889644a31b2d7401f98346d72.png

C++标准io流


C++标准库提供了4个全局流对象(cin、cout、cerr、clog):


使用cout进行标准输出,即数据从内存流向控制台(显示器)。

使用cin进行标准输入,即数据通过键盘输入到程序中。

使用cerr进行标准错误的输出。

使用clog进行日志的输出。

我们很明显可以发现 1 3 4全部是输出流 而2是输入流


C++中流的特性

流从缓冲区中读取数据 缓冲区数据读取完毕之后才会要求输入新的数据


以下面的代码为例


这里我们可以发现 其实我们只输入了一行的数据 就覆盖了 a b


fd0a2b2a98d546628ed476a85bd51135.png

输入的数据必须要类型正确

e40dbfb55558444ab9da3221ffcf0966.png


我们可以发现 输入了两个错误格式的数据 b并没有被赋值


如果要读取一整行的数据 我们只能用getline


假设我们要输入一个字符串 hello world


由于cin读取到空格便会结束 所以说我们没办法完整的输入之


这个时候就要用到我们的getline函数了

cda5d21e47144853aaf0d1e50fd0c634.png


cout 和 cin 之所以能够识别不同类型的数据 是因为 它们进行了运算符重载


095186a6b87041b69248c38a7ab80619.png

c42b3d97bfd94259aae6ea7c47e82b83.png


自定义类型的输入和输出 一般要我们来自己来重载


比如说下面的日期类


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;
}

6b727ad5734446d2956a44aa3e929246.png


在线oj题中的输出


我们使用如下格式的代码 来重复输入 输出

64d90c389b824f40afdfaaf3ce6ace0b.png


值得一提的是 我们可以使用ctrl + z来模拟文件结束的标志


C++文件io流


C++中操作一个文件流对象有下面几步


1 定义一个文件流对象


09bd54ef55004e9f96e2eabbe4397cd1.png

2 使用文件流对象以一种方式打开一个磁盘文件

c74fd006e874448e879179dd5a1c0a52.png


3. 使用流插入和流提取运算符对文件进行操作

28a3c4135da74278990065cedcc9f575.png


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();
}


最后我们看看效果


57a5500d59f94139aef5bf2c90e93124.png


以文本形式操作文件


文本形式相对于二进制形式操作 实际上就少了一个声明二进制的读写方式


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();
}


54963cc9830a477b9990322e670b0ce8.png

注意: 使用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;
}


48ea44def46c4e128b68e124bf8e49f8.png


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

b4762c4f6d31434e99e4978f64a51a48.png



它的两种用法分别是


1 将数值类型的数据转化为字符串类型


void test7()
{
  string s1;
  stringstream s;
  int a = 10;
  s << a;
  s >> s1;
  cout << s1;
}

f8f7061e4a524d4e9eac676630b0f524.png


2. 拼接字符串 例如


void test8()
{
  string s1;
  stringstream s;
  s << "hello " << "world!";
  s1 = s.str();
  cout << s1;
}

68335ff033704bb9b2bf15d8cba6eb35.png


总结


本篇博主主要介绍了C++中的文件操作和io流 还有一个简单的stringstream类

相关文章
|
2月前
|
网络协议 安全 Linux
Linux C/C++之IO多路复用(select)
这篇文章主要介绍了TCP的三次握手和四次挥手过程,TCP与UDP的区别,以及如何使用select函数实现IO多路复用,包括服务器监听多个客户端连接和简单聊天室场景的应用示例。
97 0
|
2月前
|
存储 Linux C语言
Linux C/C++之IO多路复用(aio)
这篇文章介绍了Linux中IO多路复用技术epoll和异步IO技术aio的区别、执行过程、编程模型以及具体的编程实现方式。
104 1
Linux C/C++之IO多路复用(aio)
|
2月前
|
Linux C++
Linux C/C++之IO多路复用(poll,epoll)
这篇文章详细介绍了Linux下C/C++编程中IO多路复用的两种机制:poll和epoll,包括它们的比较、编程模型、函数原型以及如何使用这些机制实现服务器端和客户端之间的多个连接。
34 0
Linux C/C++之IO多路复用(poll,epoll)
|
4月前
|
算法 C语言 C++
【C++航海王:追寻罗杰的编程之路】C++的IO流
【C++航海王:追寻罗杰的编程之路】C++的IO流
37 2
|
6月前
|
存储 C++
C++文件操作
C++文件操作
|
6月前
|
存储 编译器 C++
【C++ 初阶路】--- 类和对象(下)
【C++ 初阶路】--- 类和对象(下)
26 1
|
6月前
|
存储 编译器 C语言
【C++初阶路】--- 类和对象(中)
【C++初阶路】--- 类和对象(中)
29 1
|
6月前
|
安全 编译器 程序员
【C++初阶】--- C++入门(上)
【C++初阶】--- C++入门(上)
37 1
|
6月前
|
Linux C++
c++高级篇(三) ——Linux下IO多路复用之poll模型
c++高级篇(三) ——Linux下IO多路复用之poll模型