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()函数避免多读最后一行:
Node* readTxt(){
FILE* fp = NULL;
Node* head = NULL;
fp = fopen("file.txt","r");
if(fp == NULL){
cout<<"Error(fopen):fp == NULL"<<endl;
return NULL;
}
while (!feof(fp))
{
Data data;
int res = fscanf(fp,"%d %s %lf\n",&data.num,data.str,&data.dou);
cout<<"res == "<<res<<endl;
14 if(res == -1){
15 break;
16 }
insert(head,&data);
}
fclose(fp);
return head;
}
2.2 fread()函数避免多读取最后一行:
Node* readBit(){
FILE* fp = NULL;
Node* head = NULL;
fp = fopen("fileBit.txt","r");
if(fp == NULL){
cout<<"Error(fopen):fp == NULL"<<endl;
return NULL;
}
while (!feof(fp))
{
Data data;
int res = fread(&data,sizeof(Data),,fp);
cout<<"res == "<<res<<endl;
14 if(res == 0){
15 break;
16 }
insert(head,&data);
}
fclose(fp);
return head;
}
完整测试代码:
#include<iostream>
#include<stdlib.h>
using namespace std; typedef struct{
int num;
char str[];
double dou;
}Data; typedef struct node{
Data data;
struct node* next;
}Node; Data* input();
void insert(Node*& head,Data* data);
void enterData(Node*& head);
void listData(Node* head,void visit(Data* item));
void visit(Data* item);
void saveTxt(Node* head);
Node* readTxt();
void saveBit(Node* head);
Node* readBit(); Data* input(){
Data* data = (Data*)calloc(,sizeof(Data));
cout<<"An Int:";
cin>>data->num;
cout<<"a string:";
cin>>data->str;
cout<<"a double:";
cin>>data->dou;
return data;
} void insert(Node*& head,Data* data){
if(data == NULL){
cout<<"Error:data == NULL\n";
return;
}
if(head == NULL){
head = (Node*)calloc(,sizeof(Node));
head->data = *data;
head->next = NULL;
}else{
Node* node = (Node*)calloc(,sizeof(Node));
node->data = *data;
node->next = head->next;
head->next = node;
}
} void enterData(Node*& head){
char c;
do
{
Data* p = input();
insert(head,p);
cout<<"continue?[y/n]:";
cin>>c;
} while (c=='y'||c=='Y');
} void visit(Data* item){
if(item == NULL){
cout<<"Error(visit):item == NULL"<<endl;
}
cout<<"Int="<<item->num<<" str="<<item->str<<" double="<<item->dou<<endl;
}
void listData(Node* head,void visit(Data* item)){
if(head == NULL){
cout<<"Error(listData):head == NULL"<<endl;
}
Node* p = head;
while (p!=NULL)
{
visit(&(p->data));
p = p->next;
}
} void saveTxt(Node* head){
int inres = ;
FILE* fp = NULL;
if(head == NULL){
cout<<"Error(saveTxt):head == NULL"<<endl;
return;
}
fp = fopen("file.txt","w");
if(fp == NULL){
cout<<"Error(fopen):fp == NULL"<<endl;
return;
}
Node* p = head;
while (p!=NULL)
{
inres = fprintf(fp,"%d %s %lf\n",p->data.num,p->data.str,p->data.dou);
cout<<"inres == "<<inres<<endl;
p = p->next;
}
fclose(fp);
} Node* readTxt(){
FILE* fp = NULL;
Node* head = NULL;
fp = fopen("file.txt","r");
if(fp == NULL){
cout<<"Error(fopen):fp == NULL"<<endl;
return NULL;
}
while (!feof(fp))
{
Data data;
int res = fscanf(fp,"%d %s %lf\n",&data.num,data.str,&data.dou);
cout<<"res == "<<res<<endl;
if(res == -){
break;
}
insert(head,&data);
}
fclose(fp);
return head;
} void saveBit(Node* head){
FILE* fp = NULL;
if(head == NULL){
cout<<"Error(saveBit):head == NULL"<<endl;
return;
}
fp = fopen("fileBit.txt","w");
if(fp == NULL){
cout<<"Error(fopen):fp == NULL"<<endl;
return;
}
Node* p = head;
while (p!=NULL)
{
fwrite(&(p->data),sizeof(Data),,fp);
p = p->next;
}
fclose(fp);
} Node* readBit(){
FILE* fp = NULL;
Node* head = NULL;
fp = fopen("fileBit.txt","r");
if(fp == NULL){
cout<<"Error(fopen):fp == NULL"<<endl;
return NULL;
}
while (!feof(fp))
{
Data data;
int res = fread(&data,sizeof(Data),,fp);
cout<<"res == "<<res<<endl;
if(res == ){
break;
}
insert(head,&data);
}
fclose(fp);
return head;
} int main(){
Node* head = NULL,*headBit = NULL;
cout<<"sizeof(Data)=="<<sizeof(Data)<<endl;
//enterData(head);
//saveTxt(head);
head = readTxt();
saveBit(head);
cout<<"bit---------------\n";
headBit = readBit();
listData(headBit,visit);
cout<<"txt---------------\n";
listData(head,visit);
saveTxt(head);
return ;
}
fprintf与fwrite函数用法与差异的更多相关文章
- php写入文件fwrite() 函数用法
在php中,php fwrite() 函数是用于写入文件(可安全用于二进制文件).说的简单点,就是在一个文件中,添加新的内容,本篇文章收集总结了几篇关于php写入文件fwrite() 函数用法的总结, ...
- C++:fread、fwrite函数用法
主要内容: fread.fwrite函数的用法 1.函数功能 用来读写一个数据块. 2.一般调用形式 fread(buffer,size,count,fp); fwrite(buffer,size,c ...
- fread 和 fwrite 函数用法示例以及注意事项
1.函数功能 用来读写一个数据块. 2.一般调用形式 fread(buffer,size,count,fp); fwrite(buffer,size,count,fp); 3.说明 ( ...
- 【转】fread函数和fwrite函数
1.函数功能 用来读写一个数据块. 2.一般调用形式 fread(buffer,size,count,fp); fwrite(buffer,size,count,fp); 3.说明 ( ...
- select()函数用法二
Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如 connect.accept.recv或recvfrom这样的阻塞程序 ...
- C语言对文件的操作函数用法详解1
在ANSIC中,对文件的操作分为两种方式,即: 流式文件操作 I/O文件操作 一.流式文件操作 这种方式的文件操作有一个重要的结构FILE,FILE在stdio.h中定义如下: typedef str ...
- fread函数和fwrite函数
1.函数功能 用来读写一个数据块. 2.一般调用形式 fread(buffer,size,count,fp); fwrite(buffer,size,count,fp); 3.说明 ( ...
- fopen函数和fread函数、fwrite函数
fopen(打开文件) 相关函数 open,fclose 表头文件 #include<stdio.h> 定义函数 FILE * fopen(const char * path,const ...
- 关于 pgsql 数据库json几个函数用法的效率测试
关于 pgsql 数据库json几个函数用法的效率测试 关于pgsql 几个操作符的效率测试比较1. json::->> 和 ->> 测试方法:单次运行100次,运行10个单次 ...
随机推荐
- win产品密钥大搜集
Win7产品密钥大收集 一.先说的还是4枚神Key如下: KH2J9-PC326-T44D4-39H6V-TVPBY TFP9Y-VCY3P-VVH3T-8XXCC-MF4YK 236TW-X778T ...
- HUST1024 dance party(最大流)
题目大概说有n男n女,男的每回合要和不同女的跳舞,男女都有自己喜欢一起跳舞的对象,他们最多能容忍和k个不喜欢的人跳舞,问舞会最多能进行几个回合. 二分枚举回合用最大流判断:男和女各拆成两点i.i'和j ...
- 不容易系列之(4)——考新郎[HDU2049]
不容易系列之(4)——考新郎 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)To ...
- BZOJ3012 : [Usaco2012 Dec]First!
建立Trie,那么成为答案的串必须满足其终止节点到根路径上没有其它点. 对于Trie上每个节点维护一个bitset,表示哪些字符必须在哪些字符之前. 每到达一个可能成为答案的终止节点,对图进行拓扑排序 ...
- [开源框架推荐]Icepdf:纯java的pdf文档的提取和转换库
ICEpdf 是一个轻量级的开源 Java 语言的 PDF 类库.通过 ICEpdf 可以用来浏览.内容提取和转换 PDF 文档,而无须一些本地PDF库的支持. 可以用来做什么? 1.从pdf文件中提 ...
- Shell 操作练习
#! /bin/sh ############################### # -- # # author jackluo # # net.webjoy@gmail.com # ###### ...
- Web前端开发规范文档你需要知道的事--HTML、css、js、文档等需要规范内容
规范目的 为提高团队协作效率,便于后台人员添加功能及前端后期优化维护,输出高质量的文档,特制订此文档.本规范文档一经确认,前端开发人员必须按本文档规范进行前台页面开发.本文档如有不对或者不 ...
- tomcat6.0安装
tomcat的安装基本是一步一步按提示来就行了: 这里填写用户名和密码,自己一定要记住啊,下面是路径的选择 然后查看安装成功与否,打开浏览器输入 然后看到下面页面就可以了
- 【iCore3 双核心板】例程二十八:FSMC实验——读写FPGA
实验指导书及代码包下载: http://pan.baidu.com/s/1gerjjxh iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...
- zend framerwork2.X系列安装创建应用
1. 到https://github.com/zendframework/ZendSkeletonApplication下载zip包,解压到你服务器的根目录. 2. 打开windows的cmd,cd到 ...