文件操作以及相关的函数,fputc,fgetc,fputs,fgtes,fprintf,fscanf,sprintf,sscanf

博主主页:@ᰔᩚ. 一怀明月ꦿ 

❤️‍专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++

座右铭:“不要等到什么都没有了,才下定决心去做”

大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点

目录

文件操作

打开文件

文件的顺序读写

fputc字符输入函数(适合所有输入流)

fgetc(适合所有的输出流)

fputs(适合所有的输入流)

fgets(适合所有的输出流)

格式化的读写

fprintf(适合所有的输入流)

fscanf读取文件(适合所有的输出流)

屏幕这个流(stdout)输出

对比:printf/fprintf/sprintf和scanf/fscanf/sscanf

sprintf(把格式化数据转换成字符串)

sscanf(把字符串转换成相应格式化数据)


文件操作

程序文件:后缀为 .c,.cpp,.exe等

数据文件:后缀为 .txt,.doc等

文件名包含三个部分:文件路径+文件名主干+文件后缀

例如:c:\code\tsest.txt

文件操作以及相关的函数,fputc,fgetc,fputs,fgtes,fprintf,fscanf,sprintf,sscanf_第1张图片

 

文件的操作:

文件的打开

文件操作(读或写)

文件的关闭

文件指针

缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”

每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是由系统声明的。取名为FILE

文件操作以及相关的函数,fputc,fgetc,fputs,fgtes,fprintf,fscanf,sprintf,sscanf_第2张图片

 

注意:不同的c编译器的FILE类型包含的内容的不完全相同

每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE变量,并填充其中的信息

一般都是通过一个FILE的指针来维护这个FILE结构的变量。

创建一个FILE*的指针变量

FILE* pf;//文件指针变量

注意:通过文件指针变量可以访问与它关联的文件

打开文件

ASICN规定使用fopen函数来打开文件,fclose来关闭文件

fopen的原型:

FILE * fopen ( const char * filename, const char * mode );

const char * filename:文件名

const char * mode:打开方式

注意:如果打开成功,打开失败返回空指针

常见打开方式有:

"r":读

"w":写

"a":追加

"r+":可以读,可以更新

"w+":可以写,可以更新

"a+":可以追加,可以更新

创建一个文件指针去向文件中写入数据

#include
#include
#include
#include
int main()
{
    //打开文件
    FILE* pf=fopen("test.txt", "w");
    if(pf==NULL)
    {
        //printf("%s\n",strerror(errno));
        perror("fopen");//如果打开失败打印原因
        return 1;
    }
    //写文件
    //关闭文件
    fclose(pf);
    pf=NULL;
    system("pwd");
    return 0;
}

文件的顺序读写

fputc字符输入函数(适合所有输入流)

fputc向文件写数据

fputc的原型:

int fputc ( int character, FILE * stream );

int character:写的单个字符

FILE * stream:文件相关联的文件指针

#include
int main()
{
    FILE* pf=fopen("test.txt", "w");
    //写文件
    //把26个字母写到文件中
    //fputc('a',pf);
    for(int i=0;i<26;i++)
    {
        fputc('a'+i,pf);
    }
    //关闭文件
    fclose(pf);
    pf=NULL;
    return 0;
}

fgetc(适合所有的输出流)

fgetc的原型:

int fgetc ( FILE * stream );

FILE * stream :文件相关联的文件指针

返回的是ASCII码值

fgetc读取一个字符时,文件指针的位置会往后移动(注意这里的文件指针不是自己创建的那个(pf)而是系统自带的文件指针)

fgetc如果读取失败或则读取完成时,会返回一个EOF

#include
int main()
{
    FILE* pf=fopen("test.txt", "r");
    //写文件
    //从文件中读取26字母字符
    for(int i=0;i<26;i++)
    {
        int ch=fgetc(pf);
        printf("%c ",ch);
    }
    //关闭文件
    fclose(pf);
    pf=NULL;
    return 0;
}

fputs(适合所有的输入流)

fputs的原型:

int fputs ( const char * str, FILE * stream );

const char * str:写入的字符串

FILE * stream :文件相关联的文件指针

如果写入成功返回非负数,写入失败返回EOF

#include
int main()
{
    FILE* pf=fopen("test.txt", "w");
    //写文件
    //写一行数据,"hello bit"
    fputs("hello bit\n",pf);//加入'\0'可以给每次写入数据换行,如果不写'\0'不会自动换行
    fputs("hello world\n",pf);
    //关闭文件
    fclose(pf);
    pf=NULL;
    return 0;
}

fgets(适合所有的输出流)

fgets的原型:

char * fgets(char * str,int num,FILE * stream);

char * str:存放读取字符的空间

int num:读取字符的个数

FILE * stream:相关联的文件指针

最多读取num-1个字符,因为第num个字符要存放'\0'

#include
int main()
{
    FILE* pf=fopen("test.txt", "r");
    //写文件
    //从文件中读取数据
    char str[20];
    fgets(str, 5, pf);
    printf("%s\n",str);
    //关闭文件
    fclose(pf);
    pf=NULL;
    return 0;
}

格式化的读写

fprintf(适合所有的输入流)

fprintf的原型:

int fprintf ( FILE * stream, const char * format, ... );

和printf一样,只是添加了一个流,FILE * stream

#include
typedef struct S
{
    int n;
    float f;
    char arr[20];
}S;
int main()
{
    S s1={100,3.14,"zhnagsan"};
    //打开文件
    FILE* pf=fopen("test.txt","w");
    //写文件
    fprintf(pf,"%d %lf %s",s1.n,s1.f,s1.arr);
    //关闭文件
    fclose(pf);
    pf=NULL;
    return 0;
}

fscanf读取文件(适合所有的输出流)

fscanf的原型:

int fscanf ( FILE * stream, const char * format, ... );

和scanf一样,只是添加了一个流,FILE * stream

#include
typedef struct S
{
    int n;
    float f;
    char arr[20];
}S;
int main()
{
    S s1={0};
    //打开文件
    FILE* pf=fopen("test.txt","r");
    //写文件
    fscanf(pf, "%d %f %s",&s1.n,&s1.f,s1.arr);
    printf("%d %f %s",s1.n,s1.f,s1.arr);
    //关闭文件
    fclose(pf);
    pf=NULL;
    return 0;
}

读写文件的时候:文件流

终端设备->屏幕:标准输出流 stdout

终端键盘->键盘:标准输入流 stdin

终端设备->屏幕:标准错误流 stderr

C程序会默认会打开3个流:stdout,stdin,stderr

从键盘这个流(stdin)读入数据

#include
int main()
{
    char arr[20]={0};
    fgets(arr,9,stdin);
    printf("%s",arr);
    return 0;
}

屏幕这个流(stdout)输出

#include
typedef struct S
{
    int n;
    float f;
    char arr[20];
}S;
int main()
{
    S s1={0};
    fscanf(stdin,"%d %f %s",&s1.n,&s1.f,s1.arr);
    fprintf(stdout,"%d %f %s",s1.n,s1.f,s1.arr);
    return 0;
}

对比:printf/fprintf/sprintf和scanf/fscanf/sscanf

sacnf 针对标准输入流(stdin)的格式化的输入函数

printf针对标准输出流(stdout)的格式化的输入函数

fscanf针对所有的输入流(文件流/stdin)的格式化的输入函数

fprintf针对所有的输出流(文件流/stdout)的格式化的输入函数

sscanf/sprintf

sprintf(把格式化数据转换成字符串)

sprintf的原型:

int sprintf ( char * str, const char * format, ... );

char * str:存放转化后的字符串的空间

const char * format, ...:格式化的数据,'...'是可变参数,因此可以是多个格式化的数据

sscanf(把字符串转换成相应格式化数据)

sscanf的原型:

int sscanf ( const char * s, const char * format, ...);

char * str:存放转化后的字符串的空间

const char * format, ...:格式化的数据,'...'是可变参数,因此可以是多个格式化的数据

#include
typedef struct S
{
    int n;
    float f;
    char arr[20];
}S;
int main()
{
    S s1={200,3.5f,"wangwu"};
    //把一个结构体转化成字符串
    char arr[200]={0};
    sprintf(arr,"%d %f %s",s1.n,s1.f,s1.arr);
    printf("%s",arr);

    //把一个字符串转化为对应格式数据
    S s2={0};
    sscanf(arr, "%d %f %s",&s2.n,&s2.f,s2.arr);
    printf("%d %f %s",s2.n,s2.f,s2.arr);
    return 0;
}

 如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家!   

你可能感兴趣的:(C,流,文件操作,文件操作函数)