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 }

时间: 2024-10-14 03:01:53

fprintf与fwrite函数用法与差异的相关文章

fscanf函数和fprintf函数、fgets函数和fputs函数、fread函数和fwrite函数

1. fscanf 函数和 fprintf 函数 1.1 fscanf 函数 fscanf 函数只能从文本文件中按格式输入.fscanf 函数和 scanf 函数相似,只是输入的对象是磁盘上文本文件的数据.函数的调用形式如下: fscanf( 文件指针,格式控制字符串,输入项表 ); 例如,若文件指针 fp 指向一个已打开的文本文件,a.b 分别为整型变量,则以下语句从 fp 所指的文件中读入两个整数放入变量 a 和 b 中: fscanf( fp, "%d%d", &a, &

【转】fread函数和fwrite函数

1.函数功能   用来读写一个数据块. 2.一般调用形式   fread(buffer,size,count,fp);   fwrite(buffer,size,count,fp); 3.说明   (1)buffer:是一个指针,对fread来说,它是读入数据的存放地址.对fwrite来说,是要输出数据的地址.   (2)size:要读写的字节数:   (3)count:要进行读写多少个size字节的数据项:   (4)fp:文件型指针. 注意:1 完成次写操(fwrite())作后必须关闭流(

PHP的ob_start函数用法详解[php函数]

用PHP的ob_start();控制您的浏览器cache Output Control 函数可以让你自由控制脚本中数据的输出.它非常地有用,特别是对于:当你想在数据已经输出后,再输出文件头的情况.输出控制函数不对使用 header() 或 setcookie(), 发送的文件头信息产生影响,只对那些类似于 echo() 和 PHP 代码的数据块有作用. 我们先举一个简单的例子,让大家对Output Control有一个大致的印象: Example 1. CODE<?php ob_start();

python 中 print 函数用法总结

Python 思想: “一切都是对象!” 在 Python 3 中接触的第一个很大的差异就是缩进是作为语法的一部分,这和C++等其他语言确实很不一样,所以要小心 ,其中python3和python2中print的用法有很多不同,python3中需要使用括号 缩进要使用4个空格(这不是必须的,但你最好这么做),缩进表示一个代码块的开始,非缩进表示一个代码的结束.没有明确的大括号.中括号.或者关键字.这意味着空白很重要,而且必须要是一致的.第一个没有缩进的行标记了代码块,意思是指函数,if 语句.

Oracle 中 decode 函数用法

Oracle 中 decode 函数用法 含义解释:decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 该函数的含义如下:IF 条件=值1 THEN RETURN(翻译值1)ELSIF 条件=值2 THEN RETURN(翻译值2) ......ELSIF 条件=值n THEN RETURN(翻译值n)ELSE RETURN(缺省值)END IFdecode(字段或字段的运算,值1,值2,值3) 这个函数运行的结果是,当字段或字段的运算的值等于值1时,该函数返回值

C#字符串的截取函数用法总结

这篇文章主要介绍了C#字符串的截取函数用法,实例总结了substring,Remove,indexOf等函数的用法,并对具体应用进行了实例分析,需要的朋友可以参考下 本文实例总结了C#常用的字符串截取函数用法.分享给大家供大家参考.具体分析如下: 在C#中字符串截取函数包括有substring 函数,Remove 函数,indexOf 函数,它们三个都可以对字符串进行截取操作,下面我们来分别介绍一下. 下面是截取字符串过程中我们必须知道的以下函数:substring 函数.Remove 函数.i

python之函数用法capitalize()

# -*- coding: utf-8 -*- #python 27 #xiaodeng #python之函数用法capitalize() #capitalize() #说明:将字符串的第一个字母变成大写,其他字母变小写. ''' capitalize(...) S.capitalize() -> string Return a copy of the string S with only its first character capitalized. ''' #案例 str='xiaoden

Python成长之路第二篇(1)_数据类型内置函数用法

数据类型内置函数用法int 关于内置方法是非常的多这里呢做了一下总结 (1)__abs__(...)返回x的绝对值 #返回x的绝对值!!!都是双下划线 x.__abs__() <==> abs(x) 例如: #!/usr/bin/python print "abs(-45) : ", abs(-45) print "abs(100.12) : ", abs(100.12) print "abs(119L) : ", abs(119L)

Python成长之路第二篇(2)_列表元组内置函数用法

列表元组内置函数用法list 元组的用法和列表相似就不一一介绍了 1)def append(self, p_object):将值添加到列表的最后 # real signature unknown; restored from __doc__ """ L.append(object) -- append object to end """ pass (2)def count(self, value): 值的出现次数 # real signature