飞码网-免费源码博客分享网站

点击这里给我发消息

在C++中如何使用顺序文件结构

飞码网-免费源码博客分享网站 本篇文章由飞码网制作上传,转载请标注来源: 飞码网-免费源码社区:https://www.codefrees.com 严禁非法转载! 本篇文章由飞码网制作上传,转载请标注来源: 飞码网-免费源码社区:https://www.codefrees.com 严禁非法转载! 飞码网-免费源码博客分享网站

在C++中如何使用顺序文件结构

          由于C++没有对文件中存储的数据施加任何结构,它们通常以无序的格式存储。因此,如果我们想在文件数据中设置任何形式的顺序,就必须通过编程来实现。本文主要介绍C++的基本文件处理能力,以期通过适当的例子来说明我们如何对文件施加一个简单的类似记录的结构。

概述

          文件是硬盘、CD、DVD、U盘、磁带等二次存储设备中永久保存数据的基本实体。但问题是,普通文件没有规定数据存储的结构,不适合高层次的数据处理。文件以原始数据字节的形式存储数据序列。需要对它们进行程序化处理,才能从中获得任何意义。不存在格式或数据上有任何结构形式的问题。因此,在任何特定格式的结构化数据的存储和检索中,它提出了一个挑战。然而,C++标准库提供了大量的支持来处理这类问题。但是,在进入它们之前,我们先来了解一下C++是如何处理文件的。

文件和流

        C++将每个文件视为一个字节序列。一个文件的结束由一个文件结束标记或一个特定的字节号来表示。这种技术是由底层操作系统的文件数据结构决定和维护的,C++在文件管理中没有作用。在C++中,通常情况下,如果一个文件已经存在,那么它就会被打开,或者创建一个与流相关的对象。C++中最常见的流对象有:cin、cout、cerr和clog。这些对象是在我们将iostream头包含到程序中时创建的。cin对象与标准输入流关联,cout与标准输出流关联,cerr和clog与标准错误流关联。注意,标准输入或输出流并不总是指键盘和屏幕/显示器。它可以是任何与输入或输出有关的设备,如触摸屏设备。错误流通常与输出设备相关联。

文件处理

         在C++中执行文件处理时,有两个不可缺少的头文件必须包含。<iostream>和<fstream>。<fstream>头中有三个重要的流类模板:执行文件输入的basic_ifstream,文件输出的basic_ofstream,文件输入和输出的basic_fstream。每个类模板的特殊性在于它们提供了预定义的操作来处理字符输入/输出。在从文件中获取有意义的数据时,将字节序列转换为字符的内置机制通常非常有用。
         需要注意的是,我们在C++程序中经常使用的ifstream、ofstream和fstream对象不过是分别是basic_ifstream、basic_ofstream和basic_fstream的特殊化。<fstream>库为基本的模板特化类提供了这些类型化的别名,以方便执行字符输入/输出到文件和从文件输入字符。

顺序文件

          一个用C++标准库函数创建的文件并不强加任何结构,如何将数据持久化。但是,我们可以根据应用程序的要求在程序上强加结构。假设一个最小的 "薪资 "应用程序将一个员工记录存储在一个顺序文件中,分别为员工id、员工姓名和工资。每个员工获得的数据构成一条记录。这些记录按顺序存储和写入文件,并以同样的方式从文件中检索或读取。以下是一个例子。
#include <string>
#include <vector>
#include <iostream>
#include <iomanip>
#include <fstream>
 
using namespace std;
 
class Employee
{
public:
   Employee(int = 0, const string & = string(""), double = 0.0);
 
   void setId(int);
   int getId() const;
 
   void setName(const string &);
   string getName() const;
 
   void setSalary(double);
   double getSalary() const;
 
private:
   int id;
   string name;
   double salary;
 
};
 
Employee::Employee(int i, const string &n, double s)
   :id(i),name(n),salary(s){}
 
void Employee::setId(int id){
   this->id = id;
}
 
int Employee::getId() const{
   return id;
}
 
void Employee::setName(const string &name){
   this->name = name;
}
 
string Employee::getName() const{
   return name;
}
 
void Employee::setSalary(double salary){
   this->salary = salary;
}
 
double Employee::getSalary() const{
   return salary;
}
 
void writeToFile(const string &filename, Employee *e){
   ofstream fout(filename, ios::app);
   if(!fout){
      cerr<<"无法打开文件进行书写"<<endl;
      exit(EXIT_FAILURE);
   }
   fout<<e->getId()<<' '<<e->getName()<<'
      '<<e->getSalary()<<endl;
   fout.close();
}
 
void readFromFile(const string &filename) {
 
   ifstream fin(filename, ios::in);
   if(!fin){
      cerr<<"无法打开文件进行书写"<<endl;
      exit(EXIT_FAILURE);
   }
   int id = 0;
   string nm = "";
   double sal = 0.0;
   cout<<"------------------------------"<<endl;
   cout << left << setw( 10 ) << "ID" << setw( 13 )
   << "NAME" << "SALARY" << endl << fixed
      << showpoint;
   cout<<"------------------------------"<<endl;
   while(fin >> id >> nm >> sal){
      cout << left << setw(10) << id << setw(13)
            << nm << setw(7) << setprecision(2)
         << right << sal << endl;
   }
   cout<<"------------------------------"<<endl;
   fin.close();
}
 
 
int main()
{
   const string filename = "payroll.dat";
 
   writeToFile(filename,new Employee(101,"Mickey",5600.00));
   writeToFile(filename,new Employee(102,"Donald",2635.00));
   writeToFile(filename,new Employee(103,"Zairo",1200.00));
 
   readFromFile(filename);
 
   return 0;
}
输入如下图所示:

打开一个文件

       在这里,我们使用ofstream类的实例打开了文件,使用两个参数:文件名和打开模式。一个文件可以用不同的模式打开,如下表所示。

文件打开模式 描述

ios::in 打开文件以读取数据。
ios::out 创建不存在的文件。当新的数据被写入文件时,所有现有的数据都会从文件中删除。
ios::app 在文件不存在的情况下创建文件。新的数据被写入文件的末尾,而不影响现有的数据。
ios::ate 打开文件进行输出。可以在文件的任何地方写入数据,类似于append。
ios::trunc 丢弃文件内容,这是 ios::out 的默认操作。
ios::binary 以二进制(非文本)模式打开文件。
           有一个open函数也可以用来打开文件并设置模式。当我们首先创建一个ofstream对象,然后按照以下方式打开它时,这个函数特别有用。

ofstream ofile.open(filename,)
ofile.open(filename, ios::out)。
在创建一个ofstream或ifstream对象后,通常会检查它是否已经成功打开。我们用下面的代码来实现。

if(!fin){
   cerr<<"无法打开文件进行写入"<<endl.EXIT_FAILURE);;。
   exit(EXIT_FAILURE);
}
          使用重载操作符 !是确定操作是否成功的一种方便方法。根据 failbit 或 badbit 中设置的值,条件返回 true 或 false。failbit是为格式错误导致的流设置的,例如当输入一个字符串值时,试图读取一个数字。badbit是为数据丢失导致的流错误而设置的。

数据处理

       数据处理发生在文件被成功打开之后。流插入(>>)和提取(<<)运算符是重载的,方便对文件进行读写数据。我们创建的文件是一个简单的文本文件,可以用任何文本编辑器查看。

关闭文件

        打开的文件必须被关闭。事实上,当我们调用与ofstream或ifstream对象相关联的close操作时,它会调用destructor,从而关闭文件。当流对象离开作用域时,该操作会自动被调用。因此,显式调用close函数是可选的,但仍然是良好的编程实践。

总结

        本文试图用一种简单的方式把如何在C++中使用顺序文件结构。<fstream>库包含了许多使用平面文件处理数据的方法。通过使用该库,可以有效地处理对文件的更复杂的操作。有许多方法和运算符重载操作,使对文件的数据处理变得简单。在这里,我们只关注顺序文件处理的初步方面。
 
飞码网-免费源码博客分享网站 本篇文章由飞码网制作上传,转载请标注来源: 飞码网-免费源码社区:https://www.codefrees.com 严禁非法转载! 本篇文章由飞码网制作上传,转载请标注来源: 飞码网-免费源码社区:https://www.codefrees.com 严禁非法转载! 飞码网-免费源码博客分享网站
赞 ()
内容页底部广告位3
留言与评论(共有 0 条评论)
   
验证码: