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

 

你可能感兴趣的:(printf)