C语言(八)

这篇博客介绍了C语言中的文件操作,包括文件的打开、关闭、读写、二进制读写以及文件指针的概念。讲解了fopen、fclose、fgetc、fgets、fprintf、fscanf、fwrite和fread等函数的使用,并提供了示例代码。还涉及到了stdio流的使用和文件的随机读写,以及fseek函数的应用。
摘要由CSDN通过智能技术生成

目录

文件

文件指针:

文件输入输出函数:

stdout的使用

fgetc()读文件示例:

写文件

读文件

二进制的读写:

写入

读取

对比一组函数

文件的随机读写

int fseek (FILE * stream, long offset,int location);


文件

磁盘上的文件是文件
一般来讲,分为:程序文件和数据文件
程序文件:包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行文件(windows环境后缀为.exe)
数据文件:文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取的文件,或者输出内容的文件

本文讨论的是数据文件。
在以前各章所处理数据的输入输出都是以终端为对象的,即从终端的键盘输入数据,运行结果显示到显示器上

文件名:一个文件需要唯一的文件标识,以便用户的识别和引用
文件名包含三部分:文件路径,文件名主干,文件后缀;
为了方便期间,文件标识常被称为文件名

文件的打开和关闭:


文件指针:


 缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”
 每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名称,文件的状态,以及文件当前的位置等)
 这些信息是被保存在一个结构体变量中的。该结构体类型是由系统声明的,取名FILE。
 
每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。
    一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便
 创建一个FILE指针
 FILE *pf
 pf指向某文件的文件信息区(是一个结构体变量)。
 通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件
比如:
如何打开和关闭文件: 
 文件打开之后需要关闭
 
int main()
{
    FILE* pf = fopen("test2.txt", "r");
    w模式可以创建不存在的文件
    r模式只会打开不存在的文件
    if (pf == NULL)
    {
        perror("fioen");
        return 1;
    }
    写文件:

    关闭文件:
    fclose(pf);
    pf = NULL;
    return 0;
}

文件输入输出函数:


硬盘上的文件数据 -->> 内存中的程序 :输入/读取
内存中的程序 -->> 硬盘上的文件数据 :输出/写入
字符输入函数:fgetc
字符输出函数:fputc
文本行输入函数:fgets
文本行输出函数:fputs
格式化输入函数:fscanf
格式化输出函数:fpintf
以上是适应于所有输入输出流,
以下适应于文件
二进制输入:fread
二进制输出:fwrite

int main()
{
    FILE* pf = fopen("test1.txt", "a+");
    w模式可以创建不存在的文件
    r模式只会打开不存在的文件
    if (pf == NULL)
    {
        perror("fioen");
        return 1;
    }
    写文件:
    fputc('\n', pf);        //单个字符输入,
    fputs("1bit", pf);        //单行文本输入
    关闭文件:
    fclose(pf);
    pf = NULL;
    return 0;
}

输出到文件


流:高度抽象的概念
程序-->>屏幕,硬盘,U盘,光盘,网络,软盘。。。
但是这种方式输出数据,不可以重用
所以就在中间加了一个层级,称为流
程序-->>流-->>其他

 

C语言程序,只要运行起来,就默认打开了三个流
stdin -- 标准输入流 -- 键盘
stdout -- 标准输出流 -- 屏幕
stderr -- 标准错误流 -- 屏幕

stdout的使用

int main()
{
    fputc('b', stdout);
    fputc('i', stdout);
    fputc('t', stdout);

    return 0;
}
//输出
bit

fgetc()读文件示例:


int main()
{
    FILE* pf = fopen("test1.txt", "r");
    w模式可以创建不存在的文件
    r模式只会打开不存在的文件
    if (pf == NULL)
    {
        perror("fioen");
        return 1;
    }
    读文件(单个字符)
    printf("%c\n", fgetc(pf));
    printf("%c\n", fgetc(pf));
    printf("%c\n", fgetc(pf));
    printf("%c\n", fgetc(pf));
    printf("%c\n", fgetc(pf));
    读取文件(单行字符)
    char arr[20] = { 0 };
    printf("%s\n", fgets(arr, 5, pf));
    当读取五个的时候,只会读取4个,因为要给arr留一个‘\0’的位置
    printf("%s\n", fgets(arr, 5, pf));
    printf("%s\n", fgets(arr, 5, pf));
    printf("%s\n", fgets(arr, 5, pf));
    printf("%s\n", fgets(arr, 5, pf));
    从标准输入流读取信息(键盘)
    printf("%c\n", fgetc(stdin));
    printf("%c\n", fgetc(stdin));
    printf("%c\n", fgetc(stdin));
    printf("%c\n", fgetc(stdin));
    printf("%c\n", fgetc(stdin));
    
    关闭文件:
    fclose(pf);
    pf = NULL;
    return 0;
}

写文件


struct s {
    char ch[10];
    int i;
    double d;
};
fprintf()函数:相比printf()多了一个参数---输入流
int main()
{
    struct s s1 = { "abcdef",10,5.5f };
    FILE* pf = fopen("test.txt", "w");
    if (NULL == pf)
    {
        perror("fopen");
        return 1;
    }
    写文件
    fprintf(pf, "%s %d %f", s1.ch, s1.i, s1.d);
    fclose(pf);
    pf = NULL;
    return 0;
}

读文件


scanf()函数
 按照某一种格式输入输出数据
int main()
{
    char ch[100] = { 0 };
    int i = 0;
    FILE* pf = fopen("test.txt", "r");
    if (NULL == pf)
    {
        perror("fopen");
        return 1;
    }
    
    fscanf(pf, "%s ", ch);//这里直接用结构体获取数据也可以
    fscanf(pf, "%d ", &i);//这里输入的应该是一个地址
    fscanf(pf, "%s ", ch);
    printf(ch);
    fclose(pf);
    pf = NULL;
    return 0;
}

二进制的读写:


写入


struct s {
    char ch[10];
    int i;
    double d;
};
int main()
{
    struct s s1 = { "abcdef",10,5.5f };
    二进制的形式写
    FILE* pf = fopen("test.txt", "w");
    if (NULL == pf)
    {
        perror("fopen");
        return 1;
    }
    写文件
    fwrite(&s1, sizeof(struct s), 1,pf);
    关闭文件
    fclose(pf);
    pf = NULL;
    return 0;
}


读取


int main()
{
    struct s s1 = { 0 };
    二进制的形式写
    FILE* pf = fopen("test.txt", "r");
    if (NULL == pf)
    {
        perror("fopen");
        return 1;
    }
    读文件
    fread(&s1, sizeof(struct s), 1, pf);
    printf("%s %d %f\n", s1.ch, s1.i, s1.d);
    关闭文件
    fclose(pf);
    pf = NULL;
    return 0;
}


fwrite写入的虽然看不懂,但是可以通过fread读取到数据;

对比一组函数


 scanf //fscanf // sscanf
 scanf -- 针对标准输入格式化的输入语句 -- stdin
 fscanf -- 针对所有输入流的格式化输入语句 -- stdin/文件
 sscanf -- 从字符串中还原为一个结构体数据
 
 printf // fprintf // sprintf
 printf -- 针对标准输出的格式化输出语句 -- stdout
 fprintf -- 针对所有输出流的格式化输出语句 -- stdout/文件
 sprintf -- 把格式化数据转换成字符串
 
struct s {
    char ch[10];
    int i;
    double d;
};
int main()
{
    struct s s1 = { "hello", 20,5.5f };
    struct s s2 = {0 };
    char buff[100] = { 0 };
    sprintf(buff, "%s %d %lf", s1.ch, s1.i, s1.d);
     sprintf -- 把格式化数据转换成字符串
    printf(buff);
    从buff字符串中还原为一个结构体数据
    sscanf(buff, "%s %d %lf", &(s2.ch), &(s2.i), &(s2.d));
    printf("%s %d %lf", s2.ch, s2.i, s2.d);
    return 0;
}
buff并不一定是结构体,其他类型也可以


文件的随机读写


int main()
{
    FILE* pf = fopen("test.txt", "r");
    if (pf == NULL)
    {
        perror("fopen");
        return 1;
    }
    读取文件
    int ch = fgetc(pf);
    printf("%c\n", ch);
    fseek(pf, -1, SEEK_CUR);
    ch = fgetc(pf);
    printf("%c\n", ch);
    ch = fgetc(pf);
    printf("%c\n", ch);
    关闭文件
    fclose(pf);
    pf = NULL;
    return 0;
}


int fseek (FILE * stream, long offset,int location);


三个参数:流,偏移量,起始位置:seek_cur--当前位置;seek_end-->文件末尾;seek_set-->文件开头


/*程序清单16.12predef.c程序
ll predef.c --预定义宏和预定义标识符*/
void why_me();
int main()
{
    printf("The file is %s. \n", __FILE__);
    printf("The date is %s. \n", __DATE__);
    printf("The time is %s. \n", __TIME__);
    printf("The version is %ld .\n", __STDC_VERSION__);
    printf("This is line %d. \n", __LINE__);
    printf("This function is %s .\n", __func__);
    why_me();

    return 0;
}
void why_me() {
    printf("This function is %s \n", __func__); 
    printf("This is line %d. \n", __LINE__);
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
2023年9月c语言级考试是一项重要的考试。随着科技的发展和信息技术的普及,掌握一门计算机编程语言变得越来越重要。C语言作为一种广泛应用的编程语言,在计算机科学和软件开发领域中具有广泛的应用。因此,参加2023年9月c语言级考试对于想要在计算机领域取得成功的人来说非常重要。 考试的时间定在2023年9月,这意味着考生有足够的时间来准备。在备考过程中,我建议首先了解考试大纲和要求,明确考试的内容和重点。然后可以参考之前的考试真题和相关教材,系统地学习C语言的基础知识和编程技巧。通过大量的练习,掌握C语言的基本语法和常用函数,并能够熟练运用它们解决实际问题。 此外,还可以参加一些培训班或在线课程,以进一步提高自己的C语言水平。在班级或学习小组中与其他学习者进行讨论和交流,互相帮助和学习,能够加深对C语言的理解和应用能力。 在考试前的最后阶段,要进行全面的复习,并重点关注自己较薄弱的知识点。可以通过刷题和模拟考试来检验和提高自己的考试能力。在考试当天,要保持冷静和自信,按照时间安排合理地回答每个问题。 总的来说,准备2023年9月c语言级考试需要充分的时间和精力投入。通过系统的学习和练习,掌握C语言的基本知识和应用能力是关键。相信只要努力备考,就一定能够在考试中取得好成绩,为自己的学习和职业发展打下坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值