C++:文件操作2 文本文件和二进制文件的读写

news/2024/9/19 16:12:24

文件读写的步骤:

1、包含的头文件:#include <fstream>//使用文件流进行操作

2、创建流

3、打开文件(文件和流关联)

4、读写 (写操作:<<,put( ), write( ) 读操作: >> , get( ),getline( ), read( ))

5、关闭文件:把缓冲区数据完整地写入文件, 添加文件结束标志, 切断流对象和外部文件的连接

---------------------------

文件的读写:

1、文本文件的读写:

方法:

一次性读写若干字符

       1)使用运算符<< 和 >>进行读写

       功能:

       << 能实现以行为单位写入文件

       >> 不能一行为单位读入内存,总是以空格、Tab、回车结束,而是以单词为单位

//函数功能:使用<< ,写入文件一行字符
#include <fstream>  
#include <iostream>  
using namespace std;
void main()
{ofstream OpenFile("file.txt");//file.txt不需要提前建立存在,执行程序时发现没有此文件会
//自己创建if (OpenFile.fail()){cout << "打开文件错误!" << endl;exit(0);}OpenFile << "abc def ghi";OpenFile.close();system("pause");
}

程序执行结果:文件中写入内容:abc def ghi

                                  

//函数功能:使用>>,从文件读入一个单词
#include <fstream>  
#include <iostream>  
using namespace std;
void main()
{const int len = 20;char str[len];ifstream OpenFile("file.txt");//必须是实现建立好已经存在的文件,否则打开文件错误if (OpenFile.fail()){cout << "打开文件错误!" << endl;exit(0);}OpenFile >> str;  //此处并不是让你输入,而是从文件中读取cout << str << endl;OpenFile.close();system("pause");
}

运行结果:str的内容为abc,而不是abc def ghi(见空格停止)

如果file.txt该文本中为空,则执行程序的结果为左图(表明文中第15行并不是类似于cin的从键盘输入操作,而此处是从文件中读取)。    如果file.txt该文本中是第一个程序执行后的结果,该程序执行结果如右图。

                                                        

2)使用运算符<<(写)和getline()进行读写

       功能:

       <<:以行为单位输入文件

       getline():以行为单位 读入内存,能一次读入一行

       函数原型:istream &getline( char *buffer, streamsize num );

       功能:getline( )函数用于从文件读取num-1个字符到buffer(内存)中,直到下列情况发生时,读取结束:

       1):num - 1个字符已经读入

       2):碰到一个换行标志

       3):碰到一个EOF

/*getline()的原型是istream& getline ( istream &is , string &str , char delim );会生成一个包含一串从输入流读入的字符的字符串,
 直到以下情况发生会导致生成的此字符串结束:1)到文件结束,2)遇到函数的定界符,3)输入达到最大限度。
getline(<字符数组chs>,<读取字符的个数n>,<终止符>)*/

//使用运算符<<(写)和getline()进行读写
#include <fstream>  
#include <iostream>  
using namespace std;  
void main()  
{  const int len=20;  char str[len];  ifstream OpenFile("file.txt");  if (OpenFile.fail())  {  cout<<"打开文件错误!"<<endl;  exit(0);  }  OpenFile.getline(str,20);  cout<<str<<endl;  OpenFile.close();  system("pause");  
} 

运行结果:str的内容为abc def ghi (一直把一行读完)

------使用读取整行文本的函数。全局函数 getline() 可以用于此目的,它也是字符串库的一部分。其用法如下。

istream& getline (istream& is, string& str, char delim = '\n');

该函数从流 is 中读取一行文本,并将其存储到字符串变量 str 中。该函数具有一个可选的形参 delim,用于标记要读取的行的结尾。分隔字符被从流中移除并丢弃。如果在没有第 3 个形参的情况下调用 getline,则分隔符被认为是行尾字符 '\n'。

第一个参数 is,必须是 istream 类的一个对象。它也可以是 istringstream、ifstream 或 fstream 类中的任何对象(如果传递了 fstream 对象,则必须打开它才能输入)。返回的值是对刚刚读取的输入流的引用。这允许测试返回值以确定调用的成功或失败,如下面的代码段所示:

string str;
if (getline(inputstream, str))
{//读取一行并存储到str中cout << str << endl;
}
else
{//出现错误或到达文件末尾
}

或者,也可以忽略返回值并在调用后的语句中测试流:

string str;
getline(inputstream, str);
if (inputstream)
{//读取一行并存储到str中cout << str << endl;
}
else
{//出现错误或到达文件末尾
}

使用 getline 函数逐行读取文件,从而保留了单词之间的白色空格:

// This program uses the getline function to read a line of information from the file.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{// Variables needed for file inputfstream nameFile;string input;// Open the filenameFile. open ("murphy.txt" , ios::in);if (!nameFile){cout << "File open error!" << endl;return 0;}// Read first line of the filegetline(nameFile, input);//该函数从流 nameFile 中读取一行文本,并将其存储到字符串变量 input 中while (nameFile){//If successful, print line and read another linecout << input << endl;getline(nameFile, input);}// Close the filenameFile.close();return 0;
}

提前建立的murphy.txt文档内容如左边;   程序执行结果如右边。

                  

由于 getline 函数的第 3 个参数在此程序中被省略了,所以它的默认值是 \n。有时可能想要指定另一个分隔符。例如,来看一个包含多个名称和地址的文件,比如存在一个addresses.txt,其内部格式如下:

可以将该文件看成是由 3 个记录组成的。记录是关于单个项目的完整信息集。另外,文件中的记录由 3 个字段组成:

  • 第一个字段就是某人的名字;
  • 第二个字段是某人的街道地址或邮政信箱号码;
  • 第三个字段包含某人的城市、州和邮政编码。

PS:请注意,每个字段以 $ 字符结尾,每个记录以 \n 字符结尾。下面的程序演示了如何使用 getline 函数来检测 $ 字符:

// This file demonstrates the getline function with a user-specified delimiter.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;int main()
{// Variable needed to read filestring input;// Open the file.fstream dataFile ("addresses.txt", ios::in);if (!dataFile){cout << "Error opening file.";return 0;}// Read lines terminated by '$'' sign and outputgetline(dataFile, input, '$');//$用于标记要读取的行的结尾while (!dataFile.fail()) //判断是否存在有效的输入流{cout << input << endl;  //输出检测到的第一个$之前的内容  并进行换行getline(dataFile, input, '$');//再次调用getline函数}// Close the filedataFile.close ();return 0;
}

此程序输出结果为:

请注意,标记每个记录结尾的 \n 字符也是输出的一部分。它们会在屏幕上打印出额外的空白行,将记录分开。

另外,使用 $ 之类的可打印字符分隔文件中的信息时,请务必选择一个实际上不会出现在信息本身中的字符。由于任何人的姓名或地址含有 $ 字符都是值得怀疑的,所以在这里它是一个可接受的分隔符。但如果文件中包含美元金额,则应该选择另一个分隔符。

while(getline())见链接:

https://mp.csdn.net/console/editor/html/104759846

 

 

 

 

 

 

 

一次读写一个字符:

使用get( )和put( )函数

函数声明:istream& get(char &c);

//使用 get( )函数 把字符1输入到文件
#include <fstream>  
#include <iostream>  
using namespace std;  
void main()  
{  char ch='1';  ofstream OpenFile("file.txt");  //该file.txt文档不需要提前建立,检测到没有此文件会自动创建if (OpenFile.fail())  {  cout<<"打开文件错误!"<<endl;  exit(0);  }  OpenFile.put(ch);  OpenFile.close();  system("pause");  
}  

运行结果:把字符1写入文件

//函数功能:使用 put( )函数 把文件中第一个字符输入内存
#include <fstream>  
#include <iostream>  
using namespace std;  
void main()  
{  char ch;  ifstream OpenFile("file.txt");  //需要提前存在file.txtif (OpenFile.fail())  {  cout<<"打开文件错误!"<<endl;  exit(0);  }  OpenFile.get(ch);  cout<<ch;  OpenFile.close();  system("pause");  
}  

运行结果:把字符1从文件中读到ch(内存)中

第15行不加<<endl输出结果为左图。   加入输出结果如右图。  PS:就是一个换行的功能

                        

2、二进制文件的读写:

  1)使用运算符get( ) 和 put( )读写一个字节

功能:

       get( ) :在文件中读取一个字节到内存

函数原型:ifstream &get(char ch)

       put( ) :在内存中写入一个字节到文件

函数原型:ofstream &put(char ch)

//功能:把26个字符写入文件中
#include <fstream>  
#include <iostream>  
using namespace std;  
void main()  
{  char ch='a';  ofstream OpenFile("file.txt",ios::binary);  //file.txt此文档无需提前建立好,检测到不存在会自动进行创建if (OpenFile.fail())  {  cout<<"打开文件错误!"<<endl;  exit(0);  }  for (int i=0;i<26;i++)  {  OpenFile.put(ch);  ch++;  }  OpenFile.close();  system("pause");  
}  

运行结果:文件内容为abcdefghijklmnopqlst...z

                       

//功能:把文件中的26个字母读入内存
#include <fstream>  
#include <iostream>  
using namespace std;  
void main()  
{  char ch;  ifstream OpenFile("file.txt",ios::binary); //file.txt需要提前建立存在 ,否则打开文件错误if (OpenFile.fail())  {  cout<<"打开文件错误!"<<endl;  exit(0);  }  while (OpenFile.get(ch))  cout<<ch;  OpenFile.close();  system("pause");  
}  

运行结果:ch依次为abc...z         PS:加入换行符<<endl的不同输出结果。

                                                              

2)使用read()和write()进行读写

  read( ):

       功能:从文件中提取 n 个字节数据,写入buf指向的地方中

       函数声明:istream &  read ( char * buf ,  int  n ) ;

      write( ):

      功能:把buf指向的内容取n个字节写入文件

      函数声明:ostream & ostream :: write ( char * buf ,  int  n ) ;

      参数说明:buf表示要写入内存的地址,传参时要取地址。n表示要读入字节的长度

      注意:1):该函数遇到空字符时并不停止,因而能够写入完整的类结构

                  2):第一个参数一个char型指针(指向内存数据的起始地址),与对象结合使用的时候,要在对象地址之前要char做强制类型转换。 

//函数功能:使用write( )函数,一次从内存向文件写入一行数据
#include <fstream>  
#include <iostream>  
using namespace std;  
void main()  
{  char ch[12]="12 3 456 78";  ofstream OpenFile("file.txt");  //不需要提前建立file.txt文件,检测到不存在会自动建立,如果提前存在,会覆盖掉原来的file.txt重新建立一个。if (OpenFile.fail())  {  cout<<"打开文件错误!"<<endl;  exit(0);  }  OpenFile.write(ch,12);  OpenFile.close();  system("pause");  
}  

运行结果:文件内容12 3 456 78

将OpenFile.write(ch,12)改变参数为OpenFile.write(ch,8),程序执行结果如右图只读取8个字节长度。

               

//函数功能:使用read()函数从文件中提取 n 个字节数据,写入buf指向的地方中
#include <fstream>  
#include <iostream>  
using namespace std;  
void main()  
{  char ch[12];  ifstream OpenFile("file.txt");  //需要提前存放好数据文档if (OpenFile.fail())  {  cout<<"打开文件错误!"<<endl;  exit(0);  }  OpenFile.read(ch,12);  cout<<ch;  OpenFile.close();  system("pause");  
}  

原始建立的文件为:

此种情况原始文件本来就存在一行:

OpenFile.read(ch,12);此中条件下的两种结果:(因为是按照字节读取,整行读取,所以整行数据并未拆分)

      

          

将原始文件增加为两行:

OpenFile.read(ch,12);此中条件下的两种结果:

                            

                     

没有读取第二行文本,因为字节数12跟8在限制。

                 

------PS:

1、程序不再使用文件时,为什么要关闭文件?

因为:1)文件缓冲区是一块小的内存空间.

            2)操作系统限制同时打开的文件数量 

注意:close ( ) 函数关闭文件,但流对象仍然存在。

2、文件的默认打开方式为文本文件,要是想以二进制的方式处理,在打开时要用 ios::binary 显式声明。

3、针对文本文件操作时,get函数和>>的区别:

区别:在读取数据时,get函数包括空白字符(遇空白字符不停止读取)

            >>在默认情况下拒绝接受空白字符(遇到空白符停止读取)

4、判断文件是否打开的方法:

//判断文件是否打开的方法:
if (OpenFile)  
{  cout<<"打开文件失败!";  exit(0);  
}  
if (OpenFile.fail())  
{  cout<<"打开文件错误!"<<endl;  exit(0);  
}  

5、判断文件是否结束的方法:

//方法1)使用成员函数eof()可以检测到这个结束符,如果非0表示文件结束。while (!OpenFile.eof())  {  //文件结束时的代码  }  
//2)使用流直接检测,如果为0表示文件结束
while (!OpenFile)  {  //文件结束时的代码  }  
//3)使用get函数,读取最后一个结束符时,返回0.读取正常情况下,返回1,并把读取的字符放到ch中
while ( (OpenFile.get(ch) )!=EOF)  {  //成功时候的代码  }  

文本文件的读写常使用的方法:使用<<写入文件,使用getline 和 >> 读到内存

二进制文件的读写常使用的方法:使用istream 类的成员函数read 和write 来实现,

这两个成员函数的原型为:

istream& read(char *buffer,int len);  
ostream& write(const char * buffer,int len);   

上述参数说明:字符指针 buffer 指向内存中一段存储空间。len 是读/写的字节数。

与对象结合写入二进制文件时:

//write函数调用语句:
输出文件流对象名.write((char*)& 对象名,sizeof(<对象所属类名>));  
输出文件流对象名.write((char*)& 对象数组名[下标],sizeof(<对象所属类名>));  
//read函数调用语句:
输入文件流对象名.read((char*)& 对象名,sizeof(<对象所属类名>));          
输入文件流对象名.read((char*)& 对象数组名[下标],sizeof(<对象所属类名>));  

PS:gcount()函数经常和read函数配合使用,用来获得实际读取的字节数。     

//二进制文件的随机读写
#include <iostream>  
#include <fstream>  
using namespace std;  
int main(void)  
{  //写文件:二进制存储1234  int writeNum1 = 1;  int writeNum2 = 2;  int writeNum3 = 3;  int writeNum4 = 4;  ofstream fout("test.txt", ios::out | ios::binary);  fout.write(reinterpret_cast<char *>(&writeNum1), sizeof(int));  fout.write(reinterpret_cast<char *>(&writeNum2), sizeof(int));  fout.write(reinterpret_cast<char *>(&writeNum3), sizeof(int));  fout.write(reinterpret_cast<char *>(&writeNum4), sizeof(int));  fout.close();  //读文件  ifstream fin("test.txt",ios::in | ios::binary);  if (!fin.good())  {  cout<<"文件打开错误"<<endl;    exit(0);  }  int readNum = 0;  //第一次输出:从第一个数字输出,结果是1 2 3 4  fin.seekg(0,ios::beg);  while (fin.peek() != EOF)  {  fin.read(reinterpret_cast<char*>(&readNum), sizeof(int));  cout<<readNum<<" ";  }  cout<<endl;  //第二次输出:从第三个数字输出,结果是3 4 fin.seekg(2 * sizeof(int),ios::beg);//游标移动的次数 = 需要处理数的个数 × int占的字节数  while (fin.peek() != EOF)  {  fin.read(reinterpret_cast<char*>(&readNum), sizeof(int));  cout<<readNum<<" ";  }  cout<<endl;  fin.close();  system("pause");  return 0;  
}  

                         

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pgtn.cn/news/18660.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript+TensorFlow.js让你在视频中瞬间消失

最近&#xff0c;一个实时人物删除&#xff08;Real Time Person removation&#xff09;的项目在GitHub上流行起来。 这个项目的神奇之处在于&#xff0c;只需要在网页浏览器中使用JavaScript&#xff0c;并使用200多行TensorFlow.js代码&#xff0c;就能让视频屏幕中的字符和…

PCB天线无线模组如何布局摆放?

随着物联网的高速发展&#xff0c;市面上涌现出越来越多的智慧产品&#xff0c;如智能家居&#xff0c;智能交通&#xff0c;智能城市等&#xff0c;这些终端设备大都靠无线收、发模块来实现信息的传递与接收。随着市场竞争的加剧&#xff0c;硬件设备正以集成化的方向发展&…

C++:while(getline())函数

首先说明getline&#xff08;&#xff09;的原型&#xff1a;getline&#xff08;istream &is,string &str,char delim&#xff09; istream &is表示一个输入流&#xff0c;譬如cin&#xff0c;string表示把从输入流读入的字符串存放在这个字符串中&#xff08;&am…

opencv隔点采样(下采样)

1、先验知识 对灰度图像来说&#xff0c;img.step[0]代表图像一行的的长度&#xff1a;img.step[0]img.cols; img.step[1]代表图像一个元素的数据大小&#xff1a;img.step[0]img.channels() ; img.data: uchar的指针&#xff0c;指向Mat数据矩阵的首地址。 2、验证&#xff1a…

C语言不完全类型是什么?有什么用途?

目录 1、不完全类型的概念 2、不完全类型的用途 3、不完全类型实践应用 1、不完全类型的概念 ISO&#xff08;国际标准化组织&#xff08;International Standard Organization&#xff09;&#xff09;将C语言分为三个不同类型集合&#xff1a; 函数类型、对象类型和不完全…

PCL:k-d tree 1 讲解

1.简介 kd-tree简称k维树&#xff0c;是一种空间划分的数据结构。常被用于高维空间中的搜索&#xff0c;比如范围搜索和最近邻搜索。kd-tree是二进制空间划分树的一种特殊情况。&#xff08;在激光雷达SLAM中&#xff0c;一般使用的是三维点云。所以&#xff0c;kd-tree的维度…

LabVIEW图像灰度分析与变换(基础篇—4)

目录 1、图像灰度分析 1.1、直方图分析 1.1.1、灰度图像直方图分析 1.1.2、彩色图像直方图分析 1.2、线灰度曲线分析 1.3、图像线灰度均值分析 1.4、图像形心和质心分析 1.5、图像灰度定量描述分析 2、图像灰度变换 1、图像灰度分析 图像灰度分析是图像分析中最基本的…

opencv线性插值(上采样)

1、调用opencv的API pyrUp(src, dst, Size(src.cols * 2, src.rows * 2)); pyrUp&#xff1a;API详解 这里的up是指将图像的尺寸变大&#xff0c;所以原始图像位于图像金字塔的顶层。 首先将当前层图像的宽高扩大2倍&#xff0c;插入的行和列位于偶数行或偶数列&#xff0c;这…