zoukankan      html  css  js  c++  java
  • C/C++程序从文本文件中读取(保存)数据

    :本文仅供初学者参阅,解惑

    • 在C程序中:

    与程序代码外的数据(文件)打交道,我们使用到流(stream)这个概念,实现进程的虚拟内存与文件之间的数据交换。

    ——文件流:C标准库提供了FILE(之所以命名为FILE,因为linux将所有机制都视为文件) ,FILE对象是一个包含了管理流所需的所有信息的结构,包括缓冲区信息、各种标记(如文件结束标记和错误标记)以及用于实际I/O的文 件描述符等。

    ——输入流,输入流:数据从文件传送到内存的叫输入流,数据从内存传送到文件的叫输出流。

    ——打开文件:FILE对象通过调用fopen函数创建的。如: FILE *fp, fp=fopen("filename","r"), 表示以只读的方式建立与filename相关的文件流;filename为当前目录下的相对路径名,r代表可读(打开文件的模式)。 

     

    一:读取

    1:对一些有规范格式文件的读取,可使用标准库stdio.h下的fscanf函数,

    函数原型为:int fscanf(FILE * stream, const char * format, [argument...])

    如读取文件data.txt(数据格式相对规范)

    代码实现读取:

    //test.c
    //文件读取
      #include<stdio.h>
      
      int main()
      {
        //1:创建文件流,文件指针名=fopen(文件名,使用文件方式)打开失败则返回NULL;
        FILE *fp=fopen("./data.txt","r"); //以data.txt文件为例
    
        //2:检测文件是否打开成功;
        if(!fp){
           printf("打开失败!
    ");
           return -1; //返回异常
        }
        //3:
        int num; //用来储存一个整型数据
        char name[10], place[10]; //用来储存两个字符串数据
    
        //抽象理解:
        //理解文件位置含义:其表示已打开文件当前可读写字符的位置,其表示为一个到文件头的整数;
        //fscanf在读取数据时可以这样理解:文件被打开后,它就成了一个无序字节流(水流),其会通过一个管道,流向被读取的一端;
        //了解fscanf后知道,其遇到空格字符(空格,制表符),换行符,就会停止,这里的停止我们可以理解为:
        //停下来为文件中两个不相关的数据块做一个分隔的操作,刚好适应了我们一般将空字符(包括换行符)作为两个数据之间的分隔的行为;
        //我们只需理解管道的两端
        //流进管道的一端的位置,就是文件的位置,表示已被读到的位置。
        //流出管道一端,就是进程用来读取数据的一端,其可以对管道中已经做区分的数据进行读取。
       
       //4:读取:
        fscanf(fp,"%d%s%s",&num, name,place); //fscanf对流的格式化读取。
        //注1:fscanf(fp,"%da%s%s",&num,name,place); 可以实现对数据:1a小刚 河南;的准确读取,表示两个数据之间以a为界。
        //注2:因为流是指针的性质,所以函数是将各数据块的首地址交给对应参数,所以num需进行&取地址操作,
        //注3:因为name,place本身已表达地址,所以不用改变;
    
        fscanf(fp,"
    ");
        //
    为控制字符,此时文件的位置到了第二行的开始;
    
        //接着进行操作:fscanf(fp,"%d%s%s",&num, name,place);就可以继续读取第二行
        //所以我们常常只需利用一个while语句就可以将整个文件读取到一个数据结构(进程)中
        /*
        while(!feof(fp)) //feof()检测一个文件是否结束,即到达文件尾,若结束,则返回非0值,否则返回0
        {
           fscanf(fp,"%d%s%s
    ",&num, name,place); 
        }
        */
     
        //检测读取结果
        printf("%d %s %s
    ",num, name, place);
     
        //关闭流
        fclose(fp); 
        
        return 0;
    
     }

    程序运行结果:

    2:从文件中读取整行数据(标准库stdio.h下的fgets

    函数原型:char *fgets(char *str, int n, FILE *stream); 

    其从指定的流 stream 读取一行,并把它存储在 str 所指向的字符串内。当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,遇到空格不停止;

    例从文件中读取一行数据:

    代码实现:

    //test3.c
    //行读取文件数据
    
    #include<stdio.h>
    #define maxlen 30
    
    int main()
    {
        //创建文件流
        FILE *fp=fopen("./data.txt","r");
        
        //2:检测文件是否打开成功;
        if(!fp){
           printf("打开失败!
    ");
           return -1; //返回异常
        }
        char str[maxlen];//缓冲区,用来储存数据
    
        //从文件中读取一行数据,储存到str开始的地址,最大长度为maxlen,然后下次读取从下行开始
        //如果该行的数据长于maxlen-1,则只能返回一个不完整的行,并下次调用时从该处开始
        fgets(str,maxlen,fp);
    
        //检测结果
        printf("%s
    ",str);
    
        //关闭流
        fclose(fp);
        return 0;
    
    }

    运行结果:


    二:保存

    1:保存与读取往往相关联,保存格式决定了你读取的方式,使用函数fprintf可以进行指定格式的保存:

    函数原型为:int fprintf( FILE *stream, const char *format, [ argument ]...) 

    假设保存一个人的个人信息到文件中:

    /*test2.c */
    //数据保存
    
    #include<stdio.h>
    
    int main()
    {
        //例一个人的信息
        int num=1;
        char name[10]="小明";
        char place[10]="河南";
    
        //建立与文件的流
        FILE *fp=fopen("./data.txt","w");
        
        //2:检测文件是否打开成功;
        if(!fp){
           printf("打开失败!
    ");
           return -1; //返回异常
        }
    
        //将数据格式化输出到指定文件流,int fprintf( FILE *stream, const char *format, [ argument ]...) 
        //注:此函数,是将format字符串写入到指定输出流中,format包括空格字符,非空格字符,说明符之中的一个或多个。如:fprintf(fp," "); 就是将空格输入到流中。
        //可理解为进程借助流将数据打印(fprintf)到了文件中;
    
        //将个人信息,写入指定流中,数据间以一个空格分隔,最后还写入换行符(控制字符)。
        fprintf(fp,"%d %s %s
    ",num, name,place);
    
        //所以常常只要利用一个while语句就可以将讲一个表(链表,顺序表)按指定行格式写入输出流中
        /*
        while(!feof(fp)) //feof()检测一个文件是否结束,即到达文件尾,若结束,则返回非0值,否则返回0
        {
           fprintf(fp,"%d %s %s
    ",num, name,place); 
        }
        */
        //关闭流
        fclose(fp);
    
        return 0;
    
    }

    运行结果:

    2:写一个字符串到流中(fputs),函数原型:int fputs(const char *str, FILE *stream);

    例:

    //test4.c
    //保存字符串
    
    #include<stdio.h>
    
    int main()
    {
        //1:创建文件流,文件指针名=fopen(文件名,使用文件方式)打开失败则返回NULL;
        FILE *fp=fopen("./data.txt","a"); //以data.txt文件为例,a表示追加
    
        //2:检测文件是否打开成功;
        if(!fp){
           printf("打开失败!
    ");
           return -1; //返回异常
        }
    
        //string
        char string[20]="Facing the world";
    
        //write string to the fstream
        fputs(string,fp);
    
        //关闭流
        fclose(fp);
    
        return 0;
    
    }

    运行结果:

    浅谈c++:


    在c++中我们可以使用操作符<<, >>来进行流的读写操作,更加的方便和易于理解;

    具体参考下列实例:

    1:读取所示数据:

    代码实现:

    //c++文件读取
    #include<iostream> //输入输出流
    #include<fstream> //文件流
    
    //using namespace std; //若使用该声明,则可以不用在使用的每个标准库的成员前加std::
    
    
    int main()
    {
       //序号,年龄,年;
       int num, age, year;
       //姓名,地址
       char name[20], place[20];
    
       //c++的文件流,ifstream为输入文件流
       std::ifstream fp;
    
       //open为ifstream的成员函数,功能为打开文件,并将它与流关联
       fp.open("./data.txt",std::ios::in); //ios::in表示读流的方式,表示打开模式。
    
       //成员函数is_open检查流是否有关联文件,即打开成功与否,成功返回true,失败返回false
       if(!fp.is_open()){
           std::cout<<"打开文件失败!!
    ";
           return 1;       // 返回异常;
       }
    
       //读取数据
       fp>>num>>year>>age>>name>>place; //使用操作符>>,将数据传输到对应的变量中
    
       //检测
       std::cout<<num<<":"<<name<<",age:"<<age<<",year:"<<year<<",live in:"<<place<<"
    "; //cout相当于printf
    
       //关闭流
       fp.close();
    
        return 0;
    }

    运行结果:

    2:往文件保存数据:

    实例:保存一个人的具体信息到文件data.txt中

    代码实现:

    //c++数据保存
    #include<iostream> //输入输出流
    #include<fstream> //文件流
    
    //using namespace std; //若使用该声明,则可以不用在使用的每个标准库的成员前加std::
    
    
    int main()
    {
       //序号,年龄,年;
       int num=3;
       int age=20;
       int year=1993;
       //姓名,地址
       char name[20]="小龙";
       char place[20]="广元";
    
       //c++的文件流,ofstream为输出文件流
       std::ofstream fp;
    
       //open为ofstream的成员函数,功能为打开文件,并将它与流关联
       fp.open("./data.txt",std::ios::app); //ios::app表示每次写入是都追加到流尾,表示打开模式。
    
       //成员函数is_open检查流是否有关联文件,即打开成功与否,成功返回true,失败返回false
       if(!fp.is_open()){
           std::cout<<"打开文件失败!!
    ";
           return 1;       // 返回异常;
       }
    
       //读取数据
       fp<<num<<" "<<year<<" "<<age<<" "<<name<<" "<<place<<"
    "; //使用操作符<<,将各数据传输到流所关联的文件中
    
       //关闭流
       fp.close();
    
        return 0;
    }

    运行结果:

  • 相关阅读:
    phonegap_android配置文档
    JQueryMobile + PhoneGap 经验总结
    nand ECC 算法记录
    u-boot 2016.05 添加自己的board 以及config.h
    git commit 多行注释方法说明
    Ubuntu 下新建用户后无法sudo
    QT4.8.5 QComboBox 增加选择菜单记录
    Linux GPIO控制方法
    Qt5 can't find -LGL
    windows 端搭建nfs 服务器
  • 原文地址:https://www.cnblogs.com/hongbo-tao/p/12050416.html
Copyright © 2011-2022 走看看