zoukankan      html  css  js  c++  java
  • fprintf与fwrite函数用法与差异

    在C语言中有两个常见的保存文件的函数:fprintf 与 fwrite。其主要用法与差异归纳如下:

    一、fprintf函数。

      1.以文本的形式保存文件。函数原型为 int fprintf(FILE* stream,const char* format,[argument]),用法类似于printf函数,返回值是输出的字符数,发生错误时返回一个负值。

      2.对应的读取函数为fscanf()。函数原型为int fscanf(FILE* stream,const char* format,[argument...]),用法类似于scanf函数,返回值为成功读入参数的个数,当读到文件末尾EOF时,返回-1。

    二、fwrite函数。

      1.以二进制形式保存文件。函数原型为size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream),参数依次为数据地址,数据元素大小,数据元素个数,文件指针。返回值为实际写入的数据的项数。

      2.对应的读取函数为fread。函数原型为size_t fread ( void *buffer, size_t size, size_t count, FILE *stream,参数依次为数据地址,数据元素大小,数据元素个数,文件指针。返回值为实际读取的数据项数,当读到文件末尾的EOF时,返回0。

    三、疑难点:

      1.由于fprintf以文本形式保存文件,所以当保存多组数据的时候,每组数据之间必须有分隔符,可以是空格,换行符或者特殊字符,否则在读取文件的时候会出错。

      2.无论哪种读取文件的方式,都可以用while(!feof(fp))来判断文件是否读到末尾,但feof()函数在读到EOF时仍然返回0,到下一个位置时才返回1,这就容易导致最后一组数据容易读取两次,或多读取一组空数据。(经试验fprint函数以空格和换行符作为数据分隔符的时候不会出现此情况)利用两个读取函数的返回值,我们可以避免这种情况。

      2.1 fscanf()函数避免多读最后一行:

     1 Node* readTxt(){
     2     FILE* fp = NULL;
     3     Node* head = NULL;
     4     fp = fopen("file.txt","r");
     5     if(fp == NULL){
     6         cout<<"Error(fopen):fp == NULL"<<endl;
     7         return NULL;
     8     }
     9     while (!feof(fp))
    10     {
    11         Data data;
    12         int res = fscanf(fp,"%d %s %lf
    ",&data.num,data.str,&data.dou);
    13         cout<<"res == "<<res<<endl;
    14         if(res == -1){
    15             break;
    16         }
    17         insert(head,&data);
    18     }
    19     fclose(fp);
    20     return head;
    21 }

      2.2 fread()函数避免多读取最后一行:

     1 Node* readBit(){
     2     FILE* fp = NULL;
     3     Node* head = NULL;
     4     fp = fopen("fileBit.txt","r");
     5     if(fp == NULL){
     6         cout<<"Error(fopen):fp == NULL"<<endl;
     7         return NULL;
     8     }
     9     while (!feof(fp))
    10     {
    11         Data data;
    12         int res = fread(&data,sizeof(Data),1,fp);
    13         cout<<"res == "<<res<<endl;
    14         if(res == 0){
    15             break;
    16         }
    17         insert(head,&data);
    18     }
    19     fclose(fp);
    20     return head;
    21 }

    完整测试代码:

      1 #include<iostream>
      2 #include<stdlib.h>
      3 using namespace std;
      4 
      5 typedef struct{
      6     int num;
      7     char str[20];
      8     double dou;
      9 }Data;
     10 
     11 typedef struct node{
     12     Data data;
     13     struct node* next;
     14 }Node;
     15 
     16 Data* input();
     17 void insert(Node*& head,Data* data);
     18 void enterData(Node*& head);
     19 void listData(Node* head,void visit(Data* item));
     20 void visit(Data* item);
     21 void saveTxt(Node* head);
     22 Node* readTxt();
     23 void saveBit(Node* head);
     24 Node* readBit();
     25 
     26 Data* input(){
     27     Data* data = (Data*)calloc(1,sizeof(Data));
     28     cout<<"An Int:";
     29     cin>>data->num;
     30     cout<<"a string:";
     31     cin>>data->str;
     32     cout<<"a double:";
     33     cin>>data->dou;
     34     return data;
     35 }
     36 
     37 void insert(Node*& head,Data* data){
     38     if(data == NULL){
     39         cout<<"Error:data == NULL
    ";
     40         return;
     41     }
     42     if(head == NULL){
     43         head = (Node*)calloc(1,sizeof(Node));
     44         head->data = *data;
     45         head->next = NULL;
     46     }else{
     47         Node* node = (Node*)calloc(1,sizeof(Node));
     48         node->data = *data;
     49         node->next = head->next;
     50         head->next = node;
     51     }
     52 }
     53 
     54 void enterData(Node*& head){
     55     char c;
     56     do 
     57     {
     58         Data* p = input();
     59         insert(head,p);
     60         cout<<"continue?[y/n]:";
     61         cin>>c;
     62     } while (c=='y'||c=='Y');
     63 }
     64 
     65 void visit(Data* item){
     66     if(item == NULL){
     67         cout<<"Error(visit):item == NULL"<<endl;
     68     }
     69     cout<<"Int="<<item->num<<" str="<<item->str<<" double="<<item->dou<<endl;
     70 }
     71 void listData(Node* head,void visit(Data* item)){
     72     if(head == NULL){
     73         cout<<"Error(listData):head == NULL"<<endl;
     74     }
     75     Node* p = head;
     76     while (p!=NULL)
     77     {
     78         visit(&(p->data));
     79         p = p->next;
     80     }
     81 }
     82 
     83 void saveTxt(Node* head){
     84     int inres = 0;
     85     FILE* fp = NULL;
     86     if(head == NULL){
     87         cout<<"Error(saveTxt):head == NULL"<<endl;
     88         return;
     89     }
     90     fp = fopen("file.txt","w");
     91     if(fp == NULL){
     92         cout<<"Error(fopen):fp == NULL"<<endl;
     93         return;
     94     }
     95     Node* p = head;
     96     while (p!=NULL)
     97     {
     98         inres = fprintf(fp,"%d %s %lf
    ",p->data.num,p->data.str,p->data.dou);
     99         cout<<"inres == "<<inres<<endl;
    100         p = p->next;
    101     }
    102     fclose(fp);
    103 }
    104 
    105 Node* readTxt(){
    106     FILE* fp = NULL;
    107     Node* head = NULL;
    108     fp = fopen("file.txt","r");
    109     if(fp == NULL){
    110         cout<<"Error(fopen):fp == NULL"<<endl;
    111         return NULL;
    112     }
    113     while (!feof(fp))
    114     {
    115         Data data;
    116         int res = fscanf(fp,"%d %s %lf
    ",&data.num,data.str,&data.dou);
    117         cout<<"res == "<<res<<endl;
    118         if(res == -1){
    119             break;
    120         }
    121         insert(head,&data);
    122     }
    123     fclose(fp);
    124     return head;
    125 }
    126 
    127 void saveBit(Node* head){
    128     FILE* fp = NULL;
    129     if(head == NULL){
    130         cout<<"Error(saveBit):head == NULL"<<endl;
    131         return;
    132     }
    133     fp = fopen("fileBit.txt","w");
    134     if(fp == NULL){
    135         cout<<"Error(fopen):fp == NULL"<<endl;
    136         return;
    137     }
    138     Node* p = head;
    139     while (p!=NULL)
    140     {
    141         fwrite(&(p->data),sizeof(Data),1,fp);
    142         p = p->next;
    143     }
    144     fclose(fp);
    145 }
    146 
    147 Node* readBit(){
    148     FILE* fp = NULL;
    149     Node* head = NULL;
    150     fp = fopen("fileBit.txt","r");
    151     if(fp == NULL){
    152         cout<<"Error(fopen):fp == NULL"<<endl;
    153         return NULL;
    154     }
    155     while (!feof(fp))
    156     {
    157         Data data;
    158         int res = fread(&data,sizeof(Data),1,fp);
    159         cout<<"res == "<<res<<endl;
    160         if(res == 0){
    161             break;
    162         }
    163         insert(head,&data);
    164     }
    165     fclose(fp);
    166     return head;
    167 }
    168 
    169 int main(){
    170     Node* head = NULL,*headBit = NULL;
    171     cout<<"sizeof(Data)=="<<sizeof(Data)<<endl;
    172     //enterData(head);
    173     //saveTxt(head);
    174     head = readTxt();
    175     saveBit(head);
    176     cout<<"bit---------------
    ";
    177     headBit = readBit();
    178     listData(headBit,visit);
    179     cout<<"txt---------------
    ";
    180     listData(head,visit);
    181     saveTxt(head);
    182     return 0;
    183 }
    View Code
  • 相关阅读:
    Coalesce (MS SQL Server)——取指定内容(列)中第一个不为空的值
    SQL 函数NULLIF、NULL、ISNULL、COALESCE、IIF
    oracle 分组后取每组第一条数据
    oracle判断是否包含字符串的方法
    Oracle 查询字段不包含多个字符串方法
    [oracle] to_date() 与 to_char() 日期和字符串转换
    Oracle中保留两位小数
    Oracle 树操作、递归查询(select…start with…connect by…prior)
    联合查询更新表数据
    WCF 之 生成元数据和代理
  • 原文地址:https://www.cnblogs.com/tangxin-blog/p/4194906.html
Copyright © 2011-2022 走看看