C++学习笔记(7)

1.创建一个顺序文件与文件输入(追加)

#include<iostream>

#include<fstream>

#include<string>

using namespace std;

 

int main()

{

   ofstream file; //注意是ofstream而不是ifstream,二者不同,见下

   file.open("1.txt", ios::out);//ios::app表示追加;ios::ate可以在文件的任何位置写数据;ios::in表示输入(但是此时文件必须是存在的,而且输入的回逐一替换以前的,但是不会一次性将以前的全部删除);ios::out表示输出(但是会删除已有内容)

   if (!file)

   {

      cerr << "File Open Error !" << endl;

      exit(1);

   }

   cout << "input the account,name,and balance" << endl;

   int account;

   string name;

   double balance;

   //当一个指针作为判定条件时,C++将一个空指针视为FALSE,非空为TRUE,这里隐式的调用了cin成员运算符void*;

   while (cin >> account >> name >> balance)

   {

      file << account << ' ' << name << ' ' << balance << endl;

   }//最终输入control+Z终止

   file.close();//当不需要时 可以显示的调用该函数来减少资源占用

}

2.从顺序文件中读取数据

#include<iostream>

#include<fstream>

#include<string>

#include<iomanip>

using namespace std;

 

void Print(int account, const string name, double balance)

{

   cout << left << setw(10) << account << setw(13) << name << setw(13) << balance << endl;

}

int main()

{

   ifstream file("1.txt", ios::in);

   if (!file)

   {

      cerr << "file open error !" << endl;

      exit(1);

   }

   cout << left << setw(10) << "Account" << setw(13) << "Name" << setw(13) << "Balance" << /*fixed << showpoint <<*/ endl;

   int account;

   string name;

   double balance;

   while (file >> account >> name >> balance)

   {

      Print(account, name, balance);

   }

   return 0;

}

重定位文件定位指针,istream和ostream都提供了成员函数来重定位文件定位指针(文件中下一个被读取或写入的字节号);在istream中,这个成员函数为seekg(),在ostream中为seekp();每个istream对象都有一个读取指针来指出文件中下一个输入的字节号,每个ostream对象都有一个写入指针来指出文件中下一个被输出的字节号;如:file.seekg(0)将定位指针重定位于文件的起始位置,其中还可以指定第二个参数来指定寻找的方向,可以是ios::beg(默认)(相对于流的开始位置进行定位);ios::end(相对于文件的末尾);ios::cur(相对于文件的当前位置)(注意数值代表的是文件开始位置到当前位置的字节数);如:file.seekg(n,ios::cur)

同样的操作可以使用osream中的seekp来实现;

成员函数tellg和tellp分别用于返回当前的“读取”和“写入”指针的位置

3.更新顺序文件:如果要将300  White  0.00数据替换成300  Worthington  0.00 的话,由于Worthington比White多了六个字符,则从“o”之后的字符就会覆盖文件中下一条顺序记录的开头;如果要使用这种方法来更新数据的话就只有用两个文件,先将该数据之前的数据拷贝到新文件中,让后再替换,之后再拷贝该数据之后的数据过去即可

实例:反复读取文件

#include<iostream>

#include<fstream>

#include<iomanip>

#include<string>

#include<stdlib.h>

using namespace std;

 

enum RequestType {ZERO_BALANCE = 1,CREDIT_BALANCE,DEBIT_BALANCE,END};

int getRequest();

bool shouldDisplay(int, double);

void outputLine(int, const string, double);

 

int main()

{

   //cout << ZERO_BALANCE << " " << CREDIT_BALANCE << " " << DEBIT_BALANCE << " " << END << endl;

   ifstream inClientFile("1.txt", ios::in);

   if (!inClientFile)

   {

      cerr << "File Opened Erro !" << endl;

      exit(1);

   }

   int request;

   int account;

   string name;

   double  balance;

   request = getRequest();

   while (request != END)

   {

      switch (request)

      {

      case ZERO_BALANCE:

          cout << " Accounts With Zero Balance : ";

          break;

      case CREDIT_BALANCE:

          cout << " Accounts With Credit Balance : ";

          break;

      case DEBIT_BALANCE:

          cout << " Accouts With Debit Balance : ";

          break;

      }

      inClientFile >> account >> name >> balance;

      while (!inClientFile.eof()) //返回一个零值,直到文件结束

      {

          if (shouldDisplay(request,balance))

          {

             outputLine(account, name, balance);

          }

          inClientFile >> account >> name >> balance;

      }

      inClientFile.clear();

      inClientFile.seekg(0);

      request = getRequest();

   }

   cout << "End Of Run !" << endl;

   return 0;

}

int getRequest()

{

   int request;

   cout << " Enter The  Request : "

      << "1-List Accounts Of Zero Balance "

      << "2-List Accounts Of Credit Balance "

      << "3-List Accounts Of Debit Balance "

      << "4-End Of Run !" << endl;

   do

   {

      cout << " ?";

      cin >> request;

   } while (request<ZERO_BALANCE && request>END);  //这里的条件不成立,所以只允许输入一次

   return request;

}

bool shouldDisplay(int type, double balance)

{

   if (type == ZERO_BALANCE && balance == 0)

      return true;

   if (type == CREDIT_BALANCE  &&balance < 0)

      return true;

   if (type == DEBIT_BALANCE && balance >0)

      return true;

   return false;

}

 

void outputLine(int account, const string name, double balance)

{

   cout << left << setw(10) << account << setw(13) << name << setw(13) << balance << endl;

}

4.随机存取文件:

  (a):创建随机存取文件

(1)ostream的成员函数write()函数可以从指定位置写入数据;istream中的read()函数可以从指定位置读取字节数据。

(2)write函数使用:file.write(reinterpret_cast<const char *>(&number),sizeof(number))  //实际上reinterpret_cast为强制类型转换,这里write函数要求const char * 类型;但是reinterpret_cast与编译器相关,所以尽量不要使用

对于read函数:file.read(reinterpret_cast<char *>(&number),sizeof(number)),要求char*类型的数据

(3)调用string类的函数将一个string数据写入到定长的char数组中(这也是为了创建随机存取文件),实例:

   string lastNameString;

   char lastName[15];

   int length = lastNameString.size();

   lastNameString.copy(lastName, length);

lastName[length] = ''; //记住最后还要自己加

(4)ofstream outFile("1.txt", ios::out | ios::binary); //ios::binary表示以二进制形式打开文件,如果要写入定长的记录,这是比要的

(5)对于既要读又要写的文件,课可以直接使用(fstream)

ifstream File("1.txt", ios::in | ios::out | ios::binary);

(6)file.clear()//表示复位文件结束指示符,一般在文件读取错误或者用户输入错误时,又要继续使用文件,此时应该调用此函数

原文地址:https://www.cnblogs.com/Con-Tch-LLYF/p/6538887.html