C语言4——文件操作

1、文件操作

int main(){
    FILE *p=fopen("D:\\temp\\a.txt","w");//用写的方式打开一个文件
    //w的意思是如果文件不存在就建立一个,如果文件存在就覆盖
    fputs("hello world",p);//向文件中写入一个字符串
    fclose(p);//关闭文件
}
int main(void){
    char s[1024]={0};
    FILE *p=fopen("D:\\temp\\a.txt");
    while(1){
        memset(s,0,sizeof(s));
        gets(s);//gets可以接收空格 而scanf("%s",s);不可以
        if(strcmp(s,"exit")==0){
            break;
        }
        int len=strlen(s);
        s[len]=‘\n‘;//由于我们并不能将scanf中输入的换行显示在文本当中 所以要在每次输入完成字符串之后 按照每次输入的内容换行
        fputs(s,p);
    }
    fclose(p);
    printf("end\n");
    return 0;
}

2、读文件

int main(){
    char s[1024]={0};
    FILE *p=fopen("D:\\temp\\a.txt","r");
    //feof(p);如果已经到了文件结尾,feof函数返回真
    while(!feof(p))//如果没有到文件结尾就一直循环
    {
        memset(s,0,sizeof(s));
        fgets(s,sizeof(s),p);//参数分别是内存地址 这块内存大小 fopen返回的文件指针
        printf("%s",s);
    }
    fclose(p);
    return 0;
}

3、文本文件加密

void code(char *s){
    while(*s){
        (*s)++;
        s++;
    }
}
void decode(char *s){
    while(*s){
        (*s)--;
        s++;
    }
}
int main(){
    char s[1024]={0};
    FILE *p=fopen("D:\\temp\\a.txt","r");
    FILE *p1=fopen("D:\\temp\\b.txt","w");
    while(!feof(p))//如果没有到文件结尾就一直循环
    {
        memset(s,0,sizeof(s));
        fgets(s,sizeof(s),p);
        code(s);
        fputs(s,p1);
    }
    fclose(p);
    fclose(p1);
    return 0;
}

4、读写方式

r 以只读方式打开文件,该文件必须存在
r+ 以可读写方式打开文件,该文件必须存在
rb+ 读写打开一个二进制文件,允许读写数据,文件必须存在
rw+ 读写打开一个文本文件,允许读和写
w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失,若文件不存在则建立该文件
w+ 打开可读写文件,若文件存在则文件长度清为0,即该文件内容会消失,若文件不存在则建立该文件
a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留(EOF符保留)
a+ 以附加的方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留(EOF符保留)

5、fopen

FILE *p=fopen("D:\\temp\\aaaa.txt","r");//如果文件打开,fopen返回打开的文件的指针,如果失败返回NULL
//FILE *p=fopen("D:\\temp\\aaaa.txt","a"); 用追加的方式打开文件,如果文件不存在,就创建这个文件,如果文件存在,就在文件结尾追加
if(p==NULL){
    printf("open fail\n");
}else{
    printf("open success\n");
}
printf("end\n");
int main(){
    FILE *p=fopen("D:\\temp\\aaaa.txt","w");
    if(p==NULL){
        printf("file open fail\n");
    }else{
        fputs("hello\n",p);
        fputs("world\n",p);
        fclose(p);
    }
    printf("end\n");
    return 0;
}
这个程序执行完成之后以16进制方式打开文件,看到
68 65 6C 6C 6F 0D 0A 77 6F 72 6C 64 0D 0A
分别对应
h  e  l  l  o  \r \n w  o  r  l  d  \r \n
int main(){
    FILE *p=fopen("D:\\temp\\aaaa.txt","wb");//如果这里加了b 则按照二进制的方式来读取文件,反之按照文本文件方式来读文件,在Windows系统中,文本模式下,文件以\r\n代表换行,若以文本模式打开文件,并用fputs等函数写入换行符"\n"时,函数会自动在"\n"前面加上"\r" 即实际写入文件的是"\r\n",而如果按照二进制方式读文件,只会读取到\n,不会读取到\r
    //在类Unix/Linux系统中文本模式下,文件以"\n"代表换行,所以Linux系统中在文本模式和二进制模式下并无区别,在Unix/Linux下w和wb是一样的
    if(p==NULL){
        printf("file open fail\n");
    }else{
        fputs("hello\n",p);
        fputs("world\n",p);
        fclose(p);
    }
    printf("end\n");
    return 0;
}
这个程序执行完成之后以16进制方式打开文件,看到
68 65 6C 6C 6F 0A 77 6F 72 6C 64 0A
分别对应
h  e  l  l  o  \n w  o  r  l  d  \n

6、getc putc

int main(){
    FILE *p=fopen("D:\\text\\a.txt","r");
    if(p==NULL){
        printf("error\n");
    }else{
        char c=0;
        //while(c!=EOF){
        //    c=getc(p);
        //    printf("%c\n",c);
        //}
        //上面while的简化写法如下
        while((c=getc(p)) != EOF){
            printf("%c",c);
        }
        fclose(p);
    }
    printf("Hello world!\n");
    return 0;
}
int main(){//写一个字符
    FILE *p=fopen("D:\\text\\a.txt","w");
    if(p==NULL){
        printf("error\n");
    }else{
        char c=0;
        putc(‘a‘,p);
        fclose(p);
    }
    printf("Hello world!\n");
    return 0;
}

7、EOF和feof

通过fgets读文件的时候通常用feof(p)判断是否到了结尾
通过getc读文件的时候通常用(c=getc(p)) != EOF判断是否到了结尾

8、文本文件排序

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
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=0;i<n;i++){
        for(j=1;j<n-i;j++){
            if(p[j-1]>p[j]){
                swap(&p[j-1],&p[j]);
            }
        }
    }
}
int main(void){
    int index;
    int array[10]={0};
    char buf[100];
    FILE *p=fopen("D:\\tmp\\a.txt",r);
    if(p==NULL){
        printf("error\n");
    }else{
        while(!feof(p)){
            memset(buf,0,sizeof(buf));//每次读取文件一行之前都把这个buffer清空
            fgets(buf,sizeof(buf),p);//从文件中读一行
            index++;
            array[index]=atoi(buf);
            fclose(p);
        }
    }
    pupple(array,index);
    p=fopen("D:\\tmp\\a.txt","w");//用写的方式打开b.txt
    int i;
    for(i=0;i<index;i++){
        memset(buf,0,sizeof(buf));//操作buf之前先将它清空
        sprintf(buf,"%d\n",array[i]);//将数组的成员转化为字符串
        fputs(buf,p);
    }
    fclose();
    return 0;
}

动态数组解决上面的问题

int main(){
    int index=0;
    char buf[100];
    FILE *p=fopen("D:\\tmp\\a.txt","r");
    while(!feof(p)){
        memset(buf,0,sizeof(buf));
        fgets(buf,sizeof(buf),p);
        index++;
    }
    fclose(p);
    int *array=calloc(sizeof(int),index);
    p=fopen("D:\\tmp\\a.txt","r");
    index=0;
    while(!feof(p)){
        memset(buf,0,sizeof(buf));
        fgets(buf,sizeof(buf),p);
        array[index]=atoi(buf);
        index++;
    }
    fclose(p);
    pupple(array,index);
    p=fopen("D:\\tmp\\b.txt","w");
    int i;
    for(i=0;i<index;i++){
        memset(buf,0,sizeof(buf));
        sprintf(buf,"%d\n",array[i]);
        fputs(buf,p);
    }
    fclose();
    return 0;
}

9、解析文件中的加减乘除

#include<stdio.h>
#include<string.h>
int calc_str(const char *s){
    char buf1[100]={0};
    char oper;
    char buf2[100]={0};
    int len=strlen(s);
    int i;
    for(i=0;i<len;i++){
        if(s[i]==‘+‘ || s[i]==‘-‘ || s[i]==‘*‘ || s[i]==‘/‘){
            strncpy(buf1,s,i);
            oper1=s[i];
            break;
        }
    }
    int start=i+1;
    for(;i<len;i++){
        if(s[i]==‘=‘){
            strncpy(buf2,&s[start],i-start);
        }
    }
    //printf("buf1=%s,oper1=%c,buf2=%s\n",buf1,oper1,buf2);
    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 0;
            }
    }
}
void curReturn(char *s){
    int len=strlen(s);
    if(s[len-1]==‘\n‘){
        s[len-1]=0;
    }
}
int main(){
    FILE *p=fopen("D:\\tmp\\a.txt","r");
    FILE *p1=fopen("D:\\tmp\\b.txt","w");
    char buf[1024];
    char buf1[1024];
    while(!feof(p)){
        memset(buf,0,sizeof(buf));
        fgets(buf,sizeof(buf),p);//从文件中读取一行记录,字符串最后是以‘\n‘结尾的
        cutReturn(buf);
        int value=calc_str(buf);
        memset(buf1,0,sizeof(buf1));
        sprintf(buf1,"%s%d\n",buf,value);
        printf("buf1=%s",buf1);
        fputs(buf1,p1);
    }
    fclose(p);
    fclose(p1);
    return 0;
}

10、fscanf

int main(){
    FILE *p=fopen("D:\\temp\\a.txt","r");
    while(!feof(p)){
        char buf[100]={0};
        //fgets(buf,sizeof(buf),p);
        fscanf(p,"%s",buf);//fscanf与scanf用法基本一致,fscanf是从一个文件读取输入,scanf是从键盘读取输入
        printf("%s",buf);
    }
    fclose(p);
    return 0;
}
int main(){
    FILE *p=fopen("D:\\temp\\a.txt","r");
    while(!feof(p)){
        char buf[100]={0};
        int a=0;
        int b=0;
        fscanf(p,"%d + %d =",&a,&b);//文件中内容必须是固定格式为xx + xx =的形式
        printf("%d %d",a,b);
    }
}

11、printf

int main(){
    FILE *p=fopen("D:\\temp\\a.txt","r");
    char buf[100]="hello world";
    fprintf(p,"%s",buf);//和printf类似,printf输出到屏幕上,fpritnf输出到文件里面
    int a=6;
    int b=7;
    fclose(p);
    return 0;
}

12、fread

int main(){
    FILE *p=fopen("D:\\tmp\\a.txt","rb");//rb代表用读二进制的方式打开一个文件
    char buf[1024]={0};
    fread(buf,sizeof(char),1,p)//第一个参数是缓冲区(存放读取的内容),第二个参数是读取的基本单元的大小
    //第三个参数是一次读取几个基本单元,第四个参数是打开的文件指针
    printf("buf=%s\n",buf);
    fclose(p);
    return 0;
}
int main(){
    FILE *p=fopen("D:\\tmp\\a.txt","rb");
    while(!feof(p)){
        char buf[10]={0};
        fread(buf,sizeof(char),sizeof(buf),p)
        printf("buf=%s\n",buf);//由于文件中每行都是以\r\n结尾的,一个字节一个字节往出读的话就会把\r\n也读到屏幕上,就会显示出非法的字符
    }
    fclose(p);
    return 0;
}
int main(){
    FILE *p=fopen("D:\\tmp\\a.txt","rb");
    while(!feof(p)){
        char buf[10]={0};
        fread(buf,sizeof(char),sizeof(buf)-1,p)//第三个参数设置为buf的长度减1是为了保证buf是一个合法的字符串(有结尾符),在下面的printf中就可以直接将读取到的字符串输出了,而且输出的过程中会根据buf最后一个0自动换行
        printf("%s",buf);
    }
    fclose(p);
    return 0;
}
int main(){
    FILE *p=fopen("D:\\tmp\\a.txt");;
    char buf[1024]={0};
    //fread返回值代表读取了多少记录数
    size_t rec=fread(buf,sizeof(char),sizeof(buf),p);//size_t是无符号整型
    printf("%u",res);//如果文件中有3个字符,返回3,有4个字符,返回4,返回的是sizeof(int)的个数
    fclose(p);
}
int main(){
    //假设a.txt中的内容是
    //ab
    //cd
    //以rb 即二进制方式读文件a.txt时,输出的是61 62 a d 63 64,其中a是\n,d是\r
    //以r  即文本文件方式读文件a.txt时,输出的是61 62 a 63 64
    //Windows下如果读取二进制文件必须要加上b,不能只写r
    FILE *p=fopen("D:\\tmp\\a.txt","rb");
    while(!feof(p)){
        char buf[1024]={0};
        int res=fread(buf,sizeof(char),sizeof(buf),p);
        int i;
        for(i=0;i<res;i++){
            printf("%x ",buf[i]);
        }
    }
    fclose(p);
    return 0;
}

13、fwrite

int main(){
    FILE *p=fopen("D:\\tmp\\a.dat","wb");
    char buf[1024]={0};
    buf[0]=‘a‘;
    buf[1]=‘b‘;
    fwrite(buf,sizeof(char),2,p);
    fclose(p);
}

14、二进制文件拷贝

#include<stdlib.h>
#include<string.h>
int main(){
    FILE *p=fopen("D:\\tmp\\a.wmv","rb");
    FILE *p1=fopen("D:\\tmp\\b.wmv","wb");
    char buf[1024 * 4];//每次读4K
    while(!feof(p)){
        memset(buf,0,sizeof(buf));
        size_t res = fread(buf,sizeof(char),sizeof(buf),p);//返回从源文件中读取的字节数
        fwrite(buf,sizeof(char),res,p1);//从源文件中读取多少字节,就往目标文件写多少字节
        //这里一定不能写成fwrite(buf,sizeof(char),sizeof(buf),p1);因为sizeof(buf)是大于等于res的,很有可能拷贝进去多余的字符,如果是拷贝二进制文件,很有可能导致二进制文件打不开
    }
    fclose(p);
    fclose(p1);
    return 0;
}

15、二进制文件的加密

#include<stdlib.h>
#include<string.h>
void code(char *p,size_t n){
    size_t i;
    for(i=0;i<n;i++){
        p[i]+=3;
    }
}
void decode(char *p,size_t n){
    size_t i;
    for(i=0;i<n;i++){
        p[i]-=3;
    }
}
int main(){
    FILE *p=fopen("D:\\tmp\\a.wmv","rb");
    FILE *p1=fopen("D:\\tmp\\b.wmv","wb");
    char buf[1024 * 4];//每次读4K
    while(!feof(p)){
        memset(buf,0,sizeof(buf));
        size_t res = fread(buf,sizeof(char),sizeof(buf),p);
        code(buf,res);
        fwrite(buf,sizeof(char),res,p1);
    }
    fclose(p);
    fclose(p1);
    return 0;
}

16、stat函数

用stat读取文件比上面的方式效率要高很多

#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
int main(){
    clock_t c1=clock();//时间戳
    struct stat st={0};
    stat("D:\\tmp\\a.txt",&st);//调用完stat函数之后,文件相关的信息就保存在stat中了
    //printf("%u\n",st.st_size);得到文件大小
    char *arr=malloc(st.st_size);//根据文件大小在堆中动态分配内存
    FILE *p=fopen("D:\\tmp\\a.txt","rb");
    fread(arr,sizeof(char),st.st_size,p);//一下把整个文件放入内存
    fclose(p);
    p=fopen("D:\\tmp\\b.wmv","wb");
    fwrite(array,sizeof(char),st.st_size,p);//将堆中的信息一下都写入文件
    fclose(p);
    clock_t c2=clock();//时间戳
    printf("%u",c2-c1);
    return 0;
}

17、结构体与二进制文件

struct student{
    char a;
    int age;
};
int main(){
    struct student st={‘a‘,25};
    FILE *p=fopen("D:\\tmp\\a.dat","wb");//a.dat里面内容是61 00 00 00 1E 00 00 00
    fwrite(&st,sizeof(st),1,p);
    fclose(p);
}

18、读取大文件

#include<time.h>
int main(){
    srand(time(NULL));
    int i;
    FILE *p=fopen("D:\\tmp\\a.txt","w");
    for(i=0;i<1000000000;i++){
        fprintf(p,"%d\n",rand() % 256);
    }
    fclose(p);
    printf("end");
    return 0;
}
//生成的a.txt会很大,大到打开a.txt时都加载不出来,几十兆就打不开了
//如果我们需要对a.txt中的数字进行排序,如果不操作堆内存的话要怎么做呢?
//先考虑小文件的情况
int main(){
    FILE *p=fopen("D:\\tmp\\a.txt","r");
    int array[256]={0};
    while(!feof(p)){
        char buf[100]={0};
        fgets(buf,sizeof(buf),p);//得到一行
        if(buf[0]!=0){//有时候我们会发现b.txt里面第一行是0,但是a.txt文件里面没有哪一行有0,那么证明a.txt文件里面的最后一行是空行
            int value=atoi(buf);//将得到的行转化为整数
            array[value]++;
        }
    }
    fclose(p);
    p=fopen("D:\\temp\\b.txt","w");
    int i;
    int j;
    for(i=0;i<513;i++){
        for(j=0;j<array[i];j++){
            fprintf(p,"%d\n",i);
        }
    }
    fclose(p);
    printf("end");
    return 0;
}

19、fseek

struct student{
    char name[10];
    int age;
};
int main01(){
    struct student st[10]={0};
    int i;
    for(i=0;i<10;i++){
        scanf("%s",st[i].name);
        scanf("%d",&st[i].age);
    }
    FILE *p=fopen("D:\\txt\\a.dat","wb");
    fwrite(st,sizeof(struct student),10,p);
    return 0;
}
int main(){
    struct student st={0};
    FILE *p=fopen("D:\\txt\\a.dat","rb");

    //读取第一个结构体
    memset(&st,0,sizeof(struct student));
    fread(&st,sizeof(struct student),1,p);
    printf("name=%s,age=%d\n",st.name,st.age);

    //读取第二个结构体
    memset(&st,0,sizeof(struct student));
    fread(&st,sizeof(struct student),1,p);
    printf("name=%s,age=%d\n",st.name,st.age);

    //读取第三个结构体
    memset(&st,0,sizeof(struct student));
    fread(&st,sizeof(struct student),1,p);
    printf("name=%s,age=%d\n",st.name,st.age);
    //目前文件指针p在第4个结构,如果在这时想回去的话,可以通过fseek实现
    //或者希望从中间开始读文件,或者倒着往回读,都可以用fseek实现
    fseek(p,sizeof(struct student),SEEK_SET);//SEEK_SET是一个宏,代表文件的开始位置,第二个参数意思是在第三个参数的基础上向后偏移sizeof(struct student)个字节读取
    //第二个参数可以是负值
    //除了SEEK_SET之外,还有SEEK_CUR(当前位置),SEEK_END(文件结尾位置)
}
时间: 2024-11-08 22:46:06

C语言4——文件操作的相关文章

C语言之文件操作08——总结

C程序的文件操作共涵盖7个例题,包含格式打印,文件读取,条件查找,矩阵的文件操作,数据格式输入及调用计算等内容. 文件操作使得程序有更强的拓展性,使其可以单独保存数据,这为程序的调试和优化打下了坚实的基础,为我们实现大规模计算提供了可能.至此,相信大家对文件操作也有了比较好的认识,无非是写入.读取.调用. 我们常常会听说C的强大,也是因为她有着文件操作的功能,而文件数据是可以方便重写和维护的. MATLAB数学软件是一款十分强大的工具型软件,它是通过C语言来表达算法的,作为面向过程的编程语言C,

015_C语言中文件操作

 文件:存储在外部介质上的数据集合 ASCII码文件和二进制文件 流式文件和非流式文件 在内存中只有1和0,电脑在显示文件时,按一定编码显示 流式文件:输入输出的数据流的开始和结束仅受程序控制而不受物理符号控制 缓冲文件和非缓冲文件 每一个使用的文件都会在内存中开辟一个缓冲区 文件打开fopen 文件关闭fclose 读到文件末尾时即读到EOF 文件操作所用到的函数fgetc/fputc  fgets/fputs   fscanf/fprintf等一些函数使用时可同过帮助文档得知 文件定位函

【C】C语言中文件操作相关内容

1. 文件和流的关系 C将每个文件简单地作为顺序字节流.每个文件用文件结束符结束,或者在特定字节数的地方结束,这个特定的字节数可以存储在系统维护的管理数据结构中.当打开文件时,就建立了和文件的关系. 在开始执行程序的时候,将自动打开3个文件和相关的流:标准输入流.标准输出流和标准错误.流提供了文件和程序的通信通道.打开一个文件将返回指向FILE结构(在stdio.h中定义)的指针,它包含用于处理文件的信息,也就是说,这个结构包含文件描述符.文件描述符是操作系统数组(打开文件列表的索引).每个数组

c语言_文件操作_FILE结构体小解释

参考文档来自:https://www.cnblogs.com/haore147/p/3648395.html 我们通过fopen返回一个文件指针(指向FILE结构体的指针)来进行文件操作. 在vs2013下的代码如下: #include <stdio.h> #pragma warning(disable:4996) int main() { FILE *p = fopen("C:\\test\\win\\a.txt", "r"); char buf[10

C#语言-07.文件操作

a. 文件操作:适用于相对简单的数据保存 i. 读写文件的步骤: 1. 创建文件流 2. 创建读写器 3. 读写文件 4. 关闭读写器 5. 关闭文件流 ii. FileStream(文件流),它主要用于读写文件中的数据,创建一个文件流时,需要指定操作文件的路径,文件的打开方式和文件的访问方式 1. 语法:FileStream 文件对象=new FileStream(String FilePath,FileMode); a. FileMode :打开文件的模式 i. 文件读写器 1. Strea

一起talk C栗子吧( 第一百四十回:C语言实例--文件操作:基于文件描述符三)

各位看官们,大家好,上一回中咱们说的是基于文件描述符进行文件操作的例子,这一回咱们继续说该例子.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,我们在上一回中详细地介绍了文件操作相关的系统调用.不过,没有举具体的例子.我们的主要内容就是举例子,因此,今天我们将通过具体的例子来说明如果使用系统调用来操作文件. 对文件的操作,还是使用我总结的文件操作三步曲比较好: fd = open(file_name,flags_read); //打开文件 fd = open(file_name,fl

C语言之文件操作01——打印1000以内的质数到文件

//文件操作 /* ========================================================== 题目:打印1000以内的质数到D盘"质数.txt"下. ========================================================== */ #include<stdio.h> void main() { FILE *fp; int n,i,k,m=0; fp=fopen("D:\\质数.t

一起talk C栗子吧(第一百四十四回:C语言实例--文件操作大结局)

各位看官们,大家好,上一回中咱们说的是基于文件指针进行文件操作的例子,这一回咱们说的是文件操作大结局.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,我们在前面章回中介绍了文件操作的两种途径:文件描述符和文件指针.今天我们将对这两种文件操作途径进行总结和对比. 我们先看看它们的共同点: 1.口味相同:都喜欢吃文件(都能用来操作文件): 2.生活方式相同:日出而作,日落而息(使用它们时都是按照文件操作三步曲进行:打开,操作,关闭): 3.都不省心:使用时容易引起错误,需要检查使用后的结

一起talk C栗子吧(第一百四十三回:C语言实例--文件操作:基于文件指针三)

各位看官们,大家好,上一回中咱们说的是基于文件指针进行文件操作的例子,这一回咱们继续说该例子.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,我们在上一回中详细地介绍了标准库中与文件操作相关的函数.不过,限于时间的原因,没有举具体的例子.还是那句老话,只说不练,不是我们的风格.因此,今天我们将通过具体的例子来说明如何使用文件指针来操作文件. 对文件的操作,还是使用我总结的文件操作三步曲比较好: p_file = fopen(file_name,"w"); //打开文件 re