• C/C++读写文件的几种方法fstream fopen、fwrite()、fread()操作


    C中采用的主要是文件指针的办法,C++中对文件的操作主要运用了“文件流”(即非标准的输入输出)的思想

    c读写文件fopen

    C 库函数
    FILE *fopen(const char *filename, const char *mode)
    

    使用给定的模式 mode 打开 filename 所指向的文件。

    包含头文件:
    #include<stdio.h>
    
    fopen() 函数的声明
    FILE *fopen(const char *filename, const char *mode)
    
    参数

    filename -- 这是 C 字符串,包含了要打开的文件名称。
    mode -- 这是 C 字符串,包含了文件访问模式,模式如下:

    r 以只读方式打开文件,该文件必须存在。
    r+ 以可读写方式打开文件,该文件必须存在。
    rb+ 读写打开一个二进制文件,允许读数据。
    rt+ 读写打开一个文本文件,允许读和写。
    w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
    w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
    a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
    a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)
    wb 只写打开或新建一个二进制文件;只允许写数据。
    wb+ 读写打开或建立一个二进制文件,允许读和写。
    wt+ 读写打开或着建立一个文本文件;允许读写。
    at+ 读写打开一个文本文件,允许读或在文本末追加数据,a表示append,就是说写入处理的时候是接着原来文件已有内容写入,不是从头写入覆盖掉,t表示打开文件的类型是文本文件,+号表示对文件既可以读也可以写。
    ab+ 读写打开一个二进制文件,允许读或在文件末追加数据。

    上述的形态字符串都可以再加一个b字符,如rb、w+b或ab+等组合,加入b 字符用来告诉函数库以二进制模式打开文件。如果不加b,表示默认加了t,即rt,wt,其中t表示以文本模式打开文件。由fopen()所建立的新文件会具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)权限,此文件权限也会参考umask 值。

    有些C编译系统可能不完全提供所有这些功能,有的C版本不用"r+","w+","a+",而用"rw","wr","ar"等,读者注意所用系统的规定。

    文件使用方式由r,w,a,t,b,+六个字符拼成,各字符的含义是:

        r(read): 读
        w(write): 写
        a(append): 追加
        t(text): 文本文件,可省略不写
        b(banary): 二进制文件
        +: 读和写
    
    二进制和文本模式的区别

    1.在windows系统中,文本模式下,文件以" "代表换行。若以文本模式打开文件,并用fputs等函数写入换行符" "时,函数会自动在" "前面加上" "。即实际写入文件的是" " 。

    2.在类Unix/Linux系统中文本模式下,文件以" "代表换行。所以Linux系统中在文本模式和二进制模式下并无区别。
    返回值 : 如果文件顺利打开,返回指向该流的文件指针。如果文件打开失败则返回NULL,并把错误代码存在error中。

    一般而言,打开文件后会作一些文件读取或写入的动作,若打开文件失败,接下来的读写动作也无法顺利进行,所以一般在fopen()后作错误判断及处理。

    fopen()函数:

    1.作用: 在C语言中fopen()函数用于打开指定路径的文件,获取指向该文件的指针。

    2.函数原型:

    FILE * fopen(const char * path,const char * mode);
        -- path: 文件路径,如:"F:Visual Stdio 2012	est.txt"
        -- mode: 文件打开方式,例如:
                 "r" 以只读方式打开文件,该文件必须存在。
                 "w" 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
                "w+" 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
                 "a" 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
                 "a+" 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。(原来的EOF符不保留)
                "wb" 只写打开或新建一个二进制文件,只允许写数据。
                "wb+" 读写打开或建立一个二进制文件,允许读和写。
                 "ab" 追加打开一个二进制文件,并在文件末尾写数据。
                 "ab+"读写打开一个二进制文件,允许读,或在文件末追加数据。   
        --返回值: 文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在errno中。        
    
    

    fwrite()函数:

    1.作用:在C语言中fwrite()函数常用语将一块内存区域中的数据写入到本地文本。

    2.函数原型:

    size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
        -- buffer:指向数据块的指针
        -- size:每个数据的大小,单位为Byte(例如:sizeof(int)就是4)
        -- count:数据个数
        -- stream:文件指针
    
    

    注意:
    返回值随着调用格式的不同而不同:

    (1) 调用格式:fwrite(buf,sizeof(buf),1,fp);

    成功写入返回值为1(即count)

    (2)调用格式:fwrite(buf,1,sizeof(buf),fp);

    成功写入则返回实际写入的数据个数(单位为Byte)

    1. 注意事项:

    写完数据后要调用fclose()关闭流,不关闭流的情况下,每次读或写数据后,文件指针都会指向下一个待写或者读数据位置的指针。

    示例说明:

    代码1: 下面代码可将1024个字(int)写入到文本文件,fwrite的调用中,size是sizeof(int),count是DATA_SIZE

    #include "stdafx.h"
    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #define DATA_SIZE 1024
     
    int main()
    {
        unsigned int *dataPtr = NULL;
        dataPtr = (unsigned int *)malloc(sizeof(int)*DATA_SIZE);
        for(unsigned int i=0;i<DATA_SIZE;i++)
        {
            dataPtr[i] = i; //初始化缓存区
        }
        FILE *fp = fopen("F:\Labwindows cvi\test.txt","w");
        fwrite(dataPtr,sizeof(int),DATA_SIZE,fp);
           fclose(fp);
           free(dataPtr);
        system("pause");
        return 0;
    }
    
    

    代码2:

    下面代码也可将1024个字写到文本中,虽然fwrite函数中,size是1,但count是DATA_SIZE*sizeof(int)。与代码1实现的结果一样。

    // datasave.cpp : 定义控制台应用程序的入口点。
    //
     
    #include "stdafx.h"
    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #define DATA_SIZE 1024
     
    int main()
    {
        unsigned int *dataPtr = NULL;
        dataPtr = (unsigned int *)malloc(sizeof(int)*DATA_SIZE);
        for(unsigned int i=0;i<DATA_SIZE;i++)
        {
            dataPtr[i] = i; //初始化缓存区
        }
        FILE *fp = fopen("F:\Labwindows cvi\test.txt","ab+");
        fwrite(dataPtr,1,DATA_SIZE*sizeof(unsigned int),fp);
    fclose(fp);
    free(dataPtr);
    
    system("pause");    
    return 0;
        
    }
    
    代码3:

    下面的代码将4096个char数据写到文本,写入的数据中,最大值为255,与上面代码1、2有区别,因为缓存区数据类型不同

    // datasave.cpp : 定义控制台应用程序的入口点。
    //
     
    #include "stdafx.h"
    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #define DATA_SIZE 1024
     
    int main()
    {
        unsigned char *dataPtr = NULL;
        dataPtr = (unsigned char *)malloc(sizeof(int)*DATA_SIZE); //申请的区域是4096个char,即1024个字的区域
        for(unsigned int i=0;i<DATA_SIZE;i++)
        {
            dataPtr[i] = i; //初始化缓存区
        }
        FILE *fp = fopen("F:\Labwindows cvi\test.txt","ab+");
        fwrite(dataPtr,sizeof(char),DATA_SIZE*sizeof(int),fp);
        fclose(fp);      
           free(dataPtr);
        system("pause");
        return 0;
    }
    
    
    代码4:

    用malloc函数申请区域时是申请的一片char*区域,通过强制类型转换后可装unsigned int 数据。

    // datasave.cpp : 定义控制台应用程序的入口点。
    //
     
    #include "stdafx.h"
    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <stdlib.h>
    #define DATA_SIZE 1024
     
    int main()
    {
        unsigned char *dataPtr = NULL;
        unsigned int *Ptr = NULL;
        dataPtr = (unsigned char *)malloc(sizeof(int)*DATA_SIZE);
        Ptr = (unsigned int *) dataPtr;
        for(unsigned int i=0;i<DATA_SIZE;i++)
        {
            Ptr[i] = i; 
        }
        FILE *fp = fopen("F:\Labwindows cvi\test.txt","ab+");
        fwrite(Ptr,sizeof(unsigned int),DATA_SIZE,fp);
        fclose(fp);
        free(dataPtr);
       system("pause");
        return 0;
    }
    
    

    fread()函数:

    1. 作用:从一个文件流中读取数据
    2. 函数原型如下:
    	size_t fread(void *buffer, size_t size, size_t count, FILE *stream);
    	  -- buffer:指向数据块的指针
    	  -- size:每个数据的大小,单位为Byte(例如:sizeof(int)就是4)
    	  -- count:数据个数
    	  -- stream:文件指针
    
    

    注意:返回值随着调用格式的不同而不同:
    (1) 调用格式:fread(buf,sizeof(buf),1,fp);
    读取成功时:当读取的数据量正好是sizeof(buf)个Byte时,返回值为1(即count)
                           否则返回值为0(读取数据量小于sizeof(buf))
    (2)调用格式:fread(buf,1,sizeof(buf),fp);
    读取成功返回值为实际读回的数据个数(单位为Byte)

    代码参考:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
     
    int main(int argc, char *argv[])
    {
    	FILE *filp = NULL;
    	char fileDir[] = "/home/yangzhiyuan/Documents/test.txt"; 
    	char dataPtr[] = "Helloworld";
    	printf("sizeof(dataPtr) = %ld
    ",sizeof(dataPtr));
    	filp = fopen(fileDir,"w+");  /* 可读可写,不存在则创建 */
    	int writeCnt = fwrite(dataPtr,sizeof(dataPtr),1,filp);  /* 返回值为1 */
    	//int writeCnt = fwrite(dataPtr,1,sizeof(dataPtr),filp);  /* 返回值为11 */
    	printf("writeCnt = %d
    ",writeCnt);
    	fclose(filp);
     
    	FILE *fp = NULL;
    	fp = fopen(fileDir,"r");
    	char buffer[256];
    	int readCnt = fread(buffer,sizeof(buffer),1,fp);  /* 返回值为0 */
    	//int readCnt = fread(buffer,1,sizeof(buffer),fp);  /* 返回值为11 */	
    	printf("readCnt = %d
    ",readCnt);
    	fclose(fp);
    	
    	printf("%s
    ",buffer);
    	exit(0);
    }
    
    
    注意:

    本例代码中定义了两个FILE变量,一个用于write,一个用于read,写完后要close掉,然后再打开,然后读。如果直接使用一个FILE变量,会出错!

    fread()函数和fwrite()函数:(可以用来实现对数据块的操作)
    // 读取文件块数据
    
    size_t fread(void *buffer, size_t size, size_t count, FILE *file);
    
    // 写入文件块数据
    
    size_t fwrite(const void *buffer, size_t size, size_t count, FILE *file);
    

    fread参数说明:buffer是读取数据后存放地址,size是的块长度,count是块的数量,实际读取长度为size*count,返回值为块成功读取块的count数量。

    fwrite参数说明:buffer是写入数据后存放地址,size是的块长度,count是块的数量,实际读取长度为size*count,返回值为块成功写入快的count数量。

    代码

    写文件

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
       FILE * fp;
    
       fp = fopen ("file.txt", "w+");
       fprintf(fp, "%s %s %s %d", "We", "are", "in", 2014);
       
       fclose(fp);
       
       return(0);
    }
    

    输出

    We are in 2014
    

    查看上面的内容:

    #include <stdio.h>
    
    int main ()
    {
       FILE *fp;
       int c;
      
       fp = fopen("file.txt","r");
       while(1)
       {
          c = fgetc(fp);
          if( feof(fp) )
          { 
              break ;
          }
          printf("%c", c);
       }
       fclose(fp);
       return(0);
    }
    

    c++ 风格的fstream

    头文件:
    #include <fstream>
    
    相关的类

    fstream提供三种类,实现C++对文件的操作

    ofstream:写操作,由ostream引申而来

    ifstream:读操作,由istream引申而来

    fstream :同时读写操作,由iostream引申而来

    文件的类型:

    文本文件 和 二进制文件

    ios::in 为输入(读)而打开文件;
    ios::out 为输出(写)而打开文件;
    ios::ate 初始位置:文件尾;
    ios::app 所有输出附加在文件末尾;
    ios::trunc 如果文件已存在则先删除该文件;
    ios::binary 二进制方式;
    ios::nocreate:不建立文件,所以文件不存在时打开失败;
    ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败;

    这些标识符可以被组合使用,中间以”或”操作符(|)间隔。例如,如果我们想要以二进制方式打开文件"example.bin" 来写入一些数据,我们可以通过以下方式调用成员函数open()来实现:

    ofstream file;
    file.open ("example.bin", ios::out | ios::app | ios::binary);
    

    ofstream, ifstream 和 fstream所有这些类的成员函数open 都包含了一个默认打开文件的方式,这三个类的默认方式各不相同:

    ofstream 默认方式 ios::out | ios::trunc
    ifstream 默认方式 ios::in
    fstream 默认方式 ios::in | ios::out

    只有当函数被调用时没有声明方式参数的情况下,默认值才会被采用。如果函数被调用时声明了任何参数,默认值将被完全改写,而不会与调用参数组合。

    由于对类ofstream, ifstream 和 fstream 的对象所进行的第一个操作通常都是打开文件,这些类都有一个构造函数可以直接调用open 函数,并拥有同样的参数。这样,我们就可以通过以下方式进行与上面同样的定义对象和打开文件的操作:

    ofstream file ("example.bin", ios::out | ios::app | ios::binary);
    

    两种打开文件的方式都是正确的。

    你可以通过调用成员函数is_open()来检查一个文件是否已经被顺利的打开了:

    bool is_open();
    

    它返回一个布尔(bool)值,为真(true)代表文件已经被顺利打开,假( false )则相反。

    关闭文件(Closing a file)
    当文件读写操作完成之后,我们必须将文件关闭以使文件重新变为可访问的。关闭文件需要调用成员函数close(),它负责将缓存中的数据排放出来并关闭文件。它的格式很简单:

    void close ();
    

    这个函数一旦被调用,原先的流对象(stream object)就可以被用来打开其它的文件了,这个文件也就可以重新被其它的进程(process)所有访问了。

    为防止流对象被销毁时还联系着打开的文件,析构函数(destructor)将会自动调用关闭函数close。

    状态标志符的验证(Verification of state flags)

    除了eof()以外,还有一些验证流的状态的成员函数(所有都返回bool型返回值):

    bad()
    如果在读写过程中出错,返回 true 。例如:当我们要对一个不是打开为写状态的文件进行写入时,或者我们要写入的设备没有剩余空间的时候。

    **fail() **
    除了与bad() 同样的情况下会返回 true 以外,加上格式错误时也返回true ,例如当想要读入一个整数,而获得了一个字母的时候。

    **eof() **
    如果读文件到达文件末尾,返回true。

    **good() **
    这是最通用的:如果调用以上任何一个函数返回true 的话,此函数返回 false 。

    要想重置以上成员函数所检查的状态标志,你可以使用成员函数clear(),没有参数。

    文件读写的步骤:

    1、包含的头文件:#include

    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");  
    
      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(见空格停止)

    2)使用运算符<<(写)和getline()进行读写
       功能:
    
       <<:以行为单位输入文件
    
       getline():以行为单位 读入内存,能一次读入一行
    
       函数原型:istream &getline( char *buffer, streamsize num );
    
       功能:getline( )函数用于从文件读取num-1个字符到buffer(内存)中,直到下列情况发生时,读取结束:
    
       1):num - 1个字符已经读入
    
       2):碰到一个换行标志
    
       3):碰到一个EOF
    

    代码

    #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 (一直把一行读完)

    一次读写一个字符:

    使用get( )和put( )函数

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

    函数功能:使用 get( )函数 把字符1输入到文件

    #include <fstream>  
    
    #include <iostream>  
    
    using namespace std;  
    
    void main()  
    
    {  
    
      char ch='1';  
    
         ofstream OpenFile("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");  
    
      if (OpenFile.fail())  
    
        {  
    
            cout<<"打开文件错误!"<<endl;  
    
            exit(0);  
    
        }  
    
        OpenFile.get(ch);  
    
        cout<<ch;  
    
        OpenFile.close();  
    
        system("pause");  
    
    }  
    

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

    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);  
    
      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);  
    
      if (OpenFile.fail())  
    
        {  
    
            cout<<"打开文件错误!"<<endl;  
    
            exit(0);  
    
        }  
    
      while (OpenFile.get(ch))  
    
            cout<<ch;  
    
        OpenFile.close();  
    
        system("pause");  
    
    }  
    

    运行结果:ch依次为abc...z

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

      read( ):

       功能:从文件中提取 n 个字节数据,写入buf指向的地方中
    
       函数声明:istream &  read ( char * buf ,  int  n ) ;
    

    代码

    函数功能:使用write( )函数,一次从内存向文件写入一行数据

    #include <fstream>  
    
    #include <iostream>  
    
    using namespace std;  
    
    void main()  
    
    {  
    
      char ch[12]="12 3 456 78";  
    
        ofstream OpenFile("file.txt");  
    
      if (OpenFile.fail())  
    
        {  
    
            cout<<"打开文件错误!"<<endl;  
    
            exit(0);  
    
        }  
    
        OpenFile.write(ch,12);  
    
        OpenFile.close();  
    
        system("pause");  
    
    }  
    

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

    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];  
    
         ifstream OpenFile("file.txt");  
    
      if (OpenFile.fail())  
    
        {  
    
            cout<<"打开文件错误!"<<endl;  
    
            exit(0);  
    
        }  
    
        OpenFile.read(ch,12);  
    
        cout<<ch;  
    
        OpenFile.close();  
    
        system("pause");  
    
    }  
    

    运行结果:数组ch的内容为12 3 456 78 。

    说明:

    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(<对象所属类名>));
    

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

    更多参考:

  • 相关阅读:
    Rabbit官方文档翻译之Publish Subscribe(三)
    Maven项目导入本地Jar包
    位运算实现整数的加减乘数运算
    SpringMVC通过工具类获取Request域
    终止线程的2种方法。标记法和中断
    Spring 下默认事务机制中@Transactional 无效的原因
    java泛型 泛型的内部原理:类型擦除以及类型擦除带来的问题
    java.lang.Object.clone()分析
    我的Node.js学习历程
    setTimeout的妙用2——防止循环超时
  • 原文地址:https://www.cnblogs.com/ZY-Dream/p/11181924.html
Copyright © 2020-2023  润新知