首页 > 代码库 > fprintf与fwrite函数用法与差异

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\n",&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 = http://www.mamicode.com/(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 =http://www.mamicode.com/= NULL){ 39         cout<<"Error:data =http://www.mamicode.com/= NULL/n"; 40         return; 41     } 42     if(head == NULL){ 43         head = (Node*)calloc(1,sizeof(Node)); 44         head->data = http://www.mamicode.com/*data; 45         head->next = NULL; 46     }else{ 47         Node* node = (Node*)calloc(1,sizeof(Node)); 48         node->data = http://www.mamicode.com/*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\n",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\n",&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---------------\n";177     headBit = readBit();178     listData(headBit,visit);179     cout<<"txt---------------\n";180     listData(head,visit);181     saveTxt(head);182     return 0;183 }
View Code

 

fprintf与fwrite函数用法与差异