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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM