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 = (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\n";
 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\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

 

posted @ 2014-12-31 02:03  你好阿汤哥  Views(12238)  Comments(0Edit  收藏  举报