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月前
|
算法 C语言 C++
【C++航海王:追寻罗杰的编程之路】C++的IO流
【C++航海王:追寻罗杰的编程之路】C++的IO流
30 2
|
4月前
|
存储 C++
C++文件操作
C++文件操作
|
4月前
|
存储 编译器 C++
【C++ 初阶路】--- 类和对象(下)
【C++ 初阶路】--- 类和对象(下)
18 1
|
4月前
|
存储 编译器 C语言
【C++初阶路】--- 类和对象(中)
【C++初阶路】--- 类和对象(中)
25 1
|
4月前
|
安全 编译器 程序员
【C++初阶】--- C++入门(上)
【C++初阶】--- C++入门(上)
27 1
|
4月前
|
Linux C++
c++高级篇(三) ——Linux下IO多路复用之poll模型
c++高级篇(三) ——Linux下IO多路复用之poll模型
|
4月前
|
缓存 监控 网络协议
c++高级篇(二) ——Linux下IO多路复用之select模型
c++高级篇(二) ——Linux下IO多路复用之select模型
|
4月前
|
存储 编译器 C++
【C++初阶】—— 类和对象 (中)
【C++初阶】—— 类和对象 (中)
33 3
|
4月前
|
编译器 C++
【C++初阶】—— 类和对象 (下)
【C++初阶】—— 类和对象 (下)
23 2