总论


1.fopen

  r以只读方式打开文件,该文件必须存在

  r+以可读写方式打开文件,文件必须存在

  rb+读写打开一个二进制文件,允许读写数据,文件必须存在

  rw+读写打开一个文本文件,允许读和写

  w 打开只写文件,若文件存在则文件长度清零,即该文件内容会消失,若文件不存在则建立该文件

  w+打开可读文件,若文件存在则文件长度清为零,即该文件内容会消失,若文件不存在则建立该文件

  a 以附加的方式打开只写文件.若文件不存在,则会建立该文件,如果存在,数据会被加到文件尾,即文件原先的内容会被保留(EOF符不保留)

  a+以附加的方式打开可读写的文件.若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留.(原来的EOF符不保留)


  • 1.文件基础操作

1.1 打开文件示例

 #include <stdio.h>

 int main()
{
FILE *p = fopen("a.txt","w");//用写的方式打开一个文件
fputs("hello",p);//向文件写入一个字符串
fclose(p);//关闭这个文件
printf("Hello World!\n");
return ;
}

QT w方式打开文件

执行完再执行一遍的时候,文件内容消失,是新的内容

 #include <stdio.h>
#include<string.h>; int main()
{
char s[] = {};
FILE *p = fopen("a.txt","w");//用写的方式打开一个文件
while()
{
memset(s,,sizeof(s));
//scanf("%s",s);
gets(s);
if(strcmp(s,"exit")==)
break;
int len = strlen(s);
s[len] = '\n';
fputs(s,p);
}
printf("Hello World!\n");
return ;
}

一个写文件实例


1.2.读文件示例

用fgets函数

 int main()
{
char s[] = {};
FILE *p = fopen("a.txt","r");//用读方式打开文件
//feof(p);//如果已经到了文件最后,函数返回真
while(!feof(p))
{
memset(s,,sizeof(s));
fgets(s,sizeof(s),p);//第一个参数是一个内存地址;第二个参数是这块内存的大小;
//第三个参数是fopen返回的指针
//每次读一行
printf("%s",s);
} fclose(p);
return ;
}

读函数实例


1.3.文件加密

 void code(char *s)
{
while(*s)//遍历一个字符串
{
(*s)++;
s++;
}
} void decode(char *s)
{
while(*s)
{
(*s)--;
s++;
}
} int main1()//加密
{
char s[] = {};
FILE *p = fopen("a.txt","r");//用读方式打开文件
FILE *p1 = fopen("b.txt","w");//用写的方式打开一个文件
//feof(p);//如果已经到了文件最后,函数返回真
while(!feof(p))
{
memset(s,,sizeof(s));
fgets(s,sizeof(s),p);//第一个参数是一个内存地址;第二个参数是这块内存的大小;
//第三个参数是fopen返回的指针
//每次读一行
code(s);
fputs(s,p1);
} fclose(p);
fclose(p1);
return ;
} int main()//解密
{
char s[] = {};
FILE *p = fopen("b.txt","r");//用读方式打开文件
FILE *p1 = fopen("c.txt","w");//用写的方式打开一个文件
//feof(p);//如果已经到了文件最后,函数返回真
while(!feof(p))
{
memset(s,,sizeof(s));
fgets(s,sizeof(s),p);//第一个参数是一个内存地址;第二个参数是这块内存的大小;
//第三个参数是fopen返回的指针
//每次读一行
decode(s);
fputs(s,p1);
} fclose(p);
fclose(p1);
return ;
}

简单文件加密解密


1.4.文本文件排序(使用冒泡排序)

 void swap(int *a,int *b)//交换参数的值
{
int tmp = *a;
*a = *b;
*b = tmp;
} void pupple(int *p,int n)//冒泡排序
{
int i;
int j;
for(i=;i<n;i++)
{
for(j=;j<n-i;j++)
{
if(p[j-]>p[j])
{
swap(&p[j-],&p[j]);
}
}
}
} int main()
{
int index = ; //这是个计数器
int array[] = {}; char buf[]; FILE *p = fopen("1.txt","r");
if(p==NULL)
{
printf("error\n");
}
else
{ while(!feof(p))//如果没有到达文件结尾,那么循环继续
{
memset(buf,,sizeof(buf));//每次去文件之前都把这个buffer清空
fgets(buf,sizeof(buf),p);//从文件中读取一行
array[index] = atoi(buf);//将读取的一行转化为int,赋值给数组成员
index++;
} fclose(p);
} pupple(array,index);//将数组排序 p = fopen("2.txt","w");//用写的方式打开2.txt
int i=;
for(i=;i<index;i++)
{
memset(buf,,sizeof(buf));//每次操作之前都把buf清空
sprintf(buf,"%d\n",array[i]);//将数组的成员转化为字符串
fputs(buf,p);
} fclose(p); return ;
}

文本文件排序

但是这样做的缺点是在栈中分配内存,很容易造成栈溢出,所以我们对main函数进行改进,动态分配数组

 int main()//在堆中建立一个数组
{
int index = ; //这是个计数器 FILE *p = fopen("1.txt","r");//第一次打开a.txt目的是要知道这个文件有多少行
while(!feof(p))//如果没有到达文件结尾,那么循环继续
{
index++;
}
fclose(p); int *array = calloc(sizeof(int),index);//在堆中建立一个动态数组 char buf[];
p = fopen("1.txt","r");
index = ;//计数器重新从0开始
if(p==NULL)
{
printf("error\n");
}
else
{ while(!feof(p))//如果没有到达文件结尾,那么循环继续
{
memset(buf,,sizeof(buf));//每次去文件之前都把这个buffer清空
fgets(buf,sizeof(buf),p);//从文件中读取一行
array[index] = atoi(buf);//将读取的一行转化为int,赋值给数组成员
index++;
} fclose(p);
} pupple(array,index);//将数组排序 p = fopen("2.txt","w");//用写的方式打开2.txt
int i=;
for(i=;i<index;i++)
{
memset(buf,,sizeof(buf));//每次操作之前都把buf清空
sprintf(buf,"%d\n",array[i]);//将数组的成员转化为字符串
fputs(buf,p);
} fclose(p); return ;
}

main函数改进,动态分配内存


1.5.解析文本内容,计算文本中的加减乘除

 #include <stdio.h>
#include <string.h> int calc_string(const char *s)
{
char buf1[] = {};
char oper1 = ;
char buf2[] = {}; int len = strlen(s);
int i;
for(i=;i<len;i++)
{
if(s[i]=='+' || s[i]=='-' ||s[i]=='*' ||s[i]=='/')
{
strncpy(buf1,s,i);
oper1 = s[i];
break;
}
} int start=i+;
for(;i<len;i++)
{
if(s[i]=='=')
{
strncpy(buf2,&s[start],i-start);
}
} switch(oper1)
{
case '+':
return atoi(buf1) + atoi(buf2);
case '-':
return atoi(buf1) - atoi(buf2);
case '*':
return atoi(buf1) * atoi(buf2);
case '/':
{
int a=atoi(buf2);
if(a)
return atoi(buf1)/atoi(buf2);
else
return ;
} }
} void cutereturn(char *s)//去掉最后最后的回车符
{
int len = strlen(s);
if(s[len-]=='\n')
s[len-]=;
} int main()
{
FILE *p = fopen("calc.txt","r");
FILE *p1 = fopen("res.txt","w");
char buf[];
char buf1[]; if(p)
{
while (!feof(p))
{
memset(buf,,sizeof(buf));
fgets(buf,sizeof(buf),p);//从文件中读取一行记录,字符串最后是一'\'结尾
cutereturn(buf); int value = calc_string(buf);
memset(buf1,,sizeof(buf1));
sprintf(buf1,"%s%d\n",buf,value);
fputs(buf1,p1);
}
} return ;
}

1.6 fscanf与fprintf的用法

 int main1()//fsancf
{
FILE *p = fopen("calc.txt","r");
while(!feof(p))
{
char buf[] = {};
//fgets(buf,sizeof(buf),p);
//fscanf(p,"%s",buf);//fscanf与scanf用法基本一致,fscanf是从一个文本读取输入,scanf是从键盘读取输入
int a;
int b;
fscanf(p,"%d+%d",&a,&b);
printf("a=%d,b=%d",a,b);
}
} void main()//fprintf
{
FILE *p =fopen("1.txt","w"); char buf[]="hello world";
int a = ;
int b = ;
fprintf(p,"%s,%d,%d",buf,a,b);//和printf功能一样,fprintf将输入到文件里面
fclose(p);
return ;
}

fscanf与fprintf

  • 二进制文本操作

2.1 二进制读取和文本读取的区别

对于传统的windows下的文件是以/r/n作为文件换行,如果是用fgets()或用fputs()函数,会做一个自动的转换,把/r/n转换成/n,写入的时候又转换成/r/n,而如果采用二进制读取的话用fread,不会做转化,/r/n会分开读取.fread不会按照一行一行来操作,而是按照一个整体来操作

 void main(void)
{
FILE *p = fopen("calc.txt","rb");//用读二进制的文件的方式打开一个文件
char buf[]={};
fread(buf,sizeof(char),sizeof(buf),p);//第一个参数是缓冲区,第二个参数是读取的时候最小单位大小,
//第三个参数是一次读取多少个单位,第四个是文件指针 printf("%s\n",buf);
return ;
}

fread

 int main()
{
FILE *p = fopen("1.txt","wb");
char buf[]={};
buf[]='a';
buf[]='b';
buf[]='\r';
buf[]='\n';
buf[]='c';
fwrite(buf,sizeof(char),,p);
fclose(p);
}

fwrite

2.2二进制文件拷贝

 int main()
{
FILE *p = fopen("a.wmv","rb");
FILE *p1 = fopen("2.wmv","wb");
char buf[*];
while(!feof(p))
{
memset(buf,,sizeof(buf));
size_t res = fread(buf,sizeof(char),sizeof(buf),p);//返回从源文件中读取的字节数
fwrite(buf,sizeof(char),res,p1);//从源文件读取多少字节,就往源文件中写入多少字节
}
fclose(p);
fclose(p1);
return ;
}

fread fwrite

2.3二进制文件加密

Code
  • 三.文件中常用操作

3.1 在堆中分配内存拷贝文件

 int main()
{
struct stat st= {};//定义一个结构,名字叫st
stat("1.txt",&st);//调用完stat函数中之后,文件相关信息就保存在st结构中了
char *array=malloc(st.st_size);//根据文件大小在堆中动态的分配一块内存
FILE *p = fopen("a.wmv","rb");
fread(array,sizeof(char),st.st_size,p);//相当于一下把整个文件放入内存
p=fopen("test.wmv","wb");
fwrite(array,sizeof(char),st.st_size,p);//将堆中的信息一下都写入文件
return ;
}

3.2结构体与二进制文件

 struct student
{
char name[];
int age;
}; int main1()
{
struct student st = {"池国维",};
FILE *p=fopen("stu.dat","wb");
fwrite(&st,sizeof(st),,p);
fclose(p);
return ;
} int main()
{
struct student st = {};
FILE *p=fopen("stu.dat","rb");
fread(&st,sizeof(st),,p);
fclose(p);
printf("name=%s,age=%d\n",st.name,st.age);
return ;
}

3.3大文件数据排序

核心思想就是以一个新的数组的下标表示数据中相应的数出现的次数

 int main()
{ FILE *p = fopen("big.txt","r");
int array[]={};
while(!feof(p))
{
char buf[]={};
fgets(buf,sizeof(buf),p);
if(buf[] != )//如果读取的行不是空行,那么久执行代码
{
int value = atoi(buf);//将得到的行转化为int
array[value]++;
} }
fclose(p); p = fopen("res.txt","w");
int i;
int j;
for(i=;i<;i++)
{
for(j=;j<array[i];j++)
{
fprintf(p,"%d\n",i);
}
}
fclose(p);
printf("end"); return ;
}

3.4文件位置操作-fseek与ftell

 struct student
{
char name[];
int age;
}; int main1()//写文件
{
struct student st[] = {}; int i;
for(i=;i<;i++)
{
printf("please input name:");
scanf("%s",st[i].name);
printf("please input age:");
scanf("%d",&st[i].age);
} FILE *p = fopen("student.dat","wb");
fwrite(st,sizeof(struct student),,p);
fclose(p);
} int main()//读文件
{
struct student st = {};
FILE *p = fopen("student.dat","rb");
// while(!feof(p))
// {
// memset(&st,0,sizeof(struct student));
// if(fread(&st,sizeof(struct student),1,p) == 0)//fread只能往前走,不能往后退
// break;
// printf("name=%s,age=%d\n",st.name,st.age);
// }
//那么如何才能在指定位置读取呢,就需要用到fseek函数 //fseek(p,sizeof(struct student),SEEK_SET);//从文件开始位置向后偏移结构student这么多的字节
memset(&st,,sizeof(struct student));
fread(&st,sizeof(struct student),,p);
printf("name=%s,age=%d\n",st.name,st.age);
fseek(p,-sizeof(struct student),SEEK_CUR);//从当前位置往回偏移
memset(&st,,sizeof(struct student));
fread(&st,sizeof(struct student),,p);
printf("name=%s,age=%d\n",st.name,st.age); printf("ftell = %d\n",ftell(p));//当前文件指针p在第7个字节 fclose(p);
return ;
}

3.5 fflush

fflush(p)将缓冲区的内容立刻写入文件,优势是不会因为停电,或者电脑死机等故障导致缓冲区内容丢失,不好的是硬盘读写次数增加,导致程序效率低下,同时硬盘寿命会变短,修改配置文件的时候,有时候会用,或者做一些不经常修改的数据,但很重要的数据,那么用fflush.

3.6 文件删除和改名

 int main()//文件删除和改名
{
remove("2.wmv");
remove("3.wmv");
remove("a.wmv");
rename("1.txt","111.txt");
}

4.C语言文件操作的更多相关文章

  1. go语言文件操作,这期资料比较详细( 欢迎加入go语言群: 218160862 )

    go语言文件操作,这期资料比较详细 欢迎加入go语言群: go语言深圳群 golang深圳 218160862 点击加入 文件操作 func Open(name string) (file *File ...

  2. C语言文件操作

    C语言文件操作,以下以基本的例子和说明来展开怎么通过C语言来进行文件操作. 操作文件,我们得需要知道什么?当然是路径和文件名. 首先我需要知道我操作的文件在哪里,叫什么名字.在C语言中还存在一个打开方 ...

  3. C 语言文件操作

    C 语言文件操作 1. 数据流:     程序与数据的交互以流的形式进行.fopen 即打开数据流,fclose 即刷新数据流.     所谓数据流,是一种抽象,表示这段数据像流一样,需要逐步接收,不 ...

  4. C语言文件操作函数

    C语言文件操作函数大全 clearerr(清除文件流的错误旗标) 相关函数 feof表头文件 #include<stdio.h> 定义函数 void clearerr(FILE * str ...

  5. C语言文件操作解析(五)之EOF解析(转载)

      C语言文件操作解析(五)之EOF解析 在C语言中,有个符号大家都应该很熟悉,那就是EOF(End of File),即文件结束符.但是很多时候对这个理解并不是很清楚,导致在写代码的时候经常出错,特 ...

  6. 【转】C语言文件操作解析(三)

    原文网址:http://www.cnblogs.com/dolphin0520/archive/2011/10/07/2200454.html C语言文件操作解析(三) 在前面已经讨论了文件打开操作, ...

  7. C语言文件操作函数大全(超详细)

    C语言文件操作函数大全(超详细) 作者: 字体:[增加 减小] 类型:转载 本篇文章是对C语言中的文件操作函数进行了详细的总结分析,需要的朋友参考下   fopen(打开文件)相关函数 open,fc ...

  8. C语言文件操作 FILE结构体

    内存中的数据都是暂时的,当程序结束时,它们都将丢失.为了永久性的保存大量的数据,C语言提供了对文件的操作. 1.文件和流 C将每个文件简单地作为顺序字节流(如下图).每个文件用文件结束符结束,或者在特 ...

  9. C语言文件操作相关函数

    在实际应用中,我们往往需要对文件进行操作,下面我将介绍C语言的一些关于操作文件的函数. 一.计算机文件 计算机文件是以计算机硬盘为载体存储在计算机上的信息集合,是存储在某种长期储存设备上的一段数据流. ...

  10. 关于C语言文件操作

    关于C语言的文件操作之前我也写过一篇博客来介绍,但是当时写的很不全面,只是简单的使用了一下 ,今天再从新学习一下. 1.文件的写 首先还是先看一个简单的例子: include<stdio.h&g ...

随机推荐

  1. Java String内存释放

    Java String内存释放 这是一个坑,Java对于String对象,不进行内存的回收: 处理大数据量的时候,少用String. 与JDK有关系:jdk1.6环境下,内存只占用10M,jdk1.8 ...

  2. MySQL之----在java编程加强知识点

    在数据中,建表处理是非经常见且非常有用的方法. 表和表之间的关系有 1:1  1:N         N:N 三种方式. 1对1的方式 <span style="font-size:1 ...

  3. JAVA网络编程--UDP通信

    首先网络传输数据需了解例如以下三点 1.找到对方IP 2.数据要发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序用数字进行了标识.为了方便称呼这个数字,叫做port,逻辑por ...

  4. m_Orchestrate learning system---十一、thinkphp查看临时文件的好处是什么

    m_Orchestrate learning system---十一.thinkphp查看临时文件的好处是什么 一.总结 一句话总结:可以知道thinkphp的标签被smarty引擎翻译而来的php代 ...

  5. ubuntu修改顶栏颜色

    title: ubuntu修改顶栏颜色 toc: false date: 2018-09-29 19:14:01 categories: methods tags: Ubuntu 编辑shell主题的 ...

  6. BOOL的getter方法

    在代码中经常会看到这样的属性声明 @property (nonatomic,assign,getter = isRead)BOOL read; 这行代码的意思就是,声明一个BOOL类型的read,但是 ...

  7. Charles抓取微信小程序数据 以及 其它应用网站数据

    为了抓取小程序数据所以使用Charles来抓取,下面介绍下使用方法(mac环境下使用).使用Charles可以非常方便的抓取Http/Https请求.官方dmg下载地址:点击此处下载 Charles抓 ...

  8. C++之易混淆知识点一-----static详解

    1.const.mutable与volatile的区别:const表明内存被初始化以后,程序将不能对它进行修改.volatile则表明,即使程序代码没有对内存单元进行修改,但是里面的值也可能会发生变化 ...

  9. latex简历遇到的问题

    博一时候简历就没弄出来,现在又要用了,于是找出当初的模板.发现问题在于编码. \XeTeXinputencoding "GBK" \XeTeXdefaultencoding &qu ...

  10. HTML&CSS——使用DIV和CSS完成网站首页重构

    1.DIV 相关的技术 Div 它是一个 html 标签,一个块级元素(单独显示一行).它单独使用没有任何意义,必须结合CSS来使用.它主要用于页面的布局. Span 它是一个 html 标签,一个内 ...