C语言第十二讲,文件操作.

       C语言第十二讲,文件操作.

一丶文件操作概述

在操作系统中,我们的文档都称为文件.操作系统也为我们提供了接口进行操作.不同语言都是使用的相同的接口,只不过封装的上层接口不一样

 操作文件的步骤

打开文件->读写文件->关闭文件.

二丶文件流的概述.

文件流称为 输入流和输出流.  其实就是从内存写数据到磁盘.和从磁盘读数据到内存.

内存->磁盘  称为输出流. 输出到磁盘

磁盘->内存 称为输入流.读取到内存.

三丶文件的打开和关闭.

1.操作原型.

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

参数1. 我们要打开的文件名. 参数二.我们打开文件的操作方式.

返回值: FILE结构体,这个结构体保存了读取文件的位置,偏移等等各种信息.

例子:

FILE *fp = fopen("D:\\demo.txt","rb");

以rb方式打开.D盘的demo.txt文件.

打开方式

说明

r

以只读方式打开文件,只允许读取,不允许写入。该文件必须存在。

r+

以读/写方式打开文件,允许读取和写入。该文件必须存在。

rb+

以读/写方式打开一个二进制文件,允许读/写数据。

rt+

以读/写方式打开一个文本文件,允许读和写。

w

以只写方式打开文件,若文件存在则长度清为0,即该文件内容消失,若不存在则创建该文件。

w+

以读/写方式打开文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。

a

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

a+

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

wb

以只写方式打开或新建一个二进制文件,只允许写数据。

wb+

以读/写方式打开或建立一个二进制文件,允许读和写。

wt+

以读/写方式打开或建立一个文本文件,允许读写。

at+

以读/写方式打开一个文本文件,允许读或在文本末追加数据。

ab+

以读/写方式打开一个二进制文件,允许读或在文件末追加数据。

文件的关闭

int fclose(FILE *fp)
例如:
fclose(fp);

其实fopen本质是调用的Windows API, CreateFile进行操作的.

四丶文件操作之文本操作,字符操作.

 文件操作有专门操作文本的一系列函数.

1.从文件中读取一个字符.写入一个字符的函数.

int fgetc (FILE *fp); 从文件中获取一个字符,读取到EOF结尾. EOF不一定是-1,不同平台不一样.
end of file 简称EOF 文件结尾.

例子:

#include<stdio.h>
int main(){
    FILE *fp;
    char ch;
   
    //如果文件不存在,给出提示并退出
    if( (fp=fopen("D:\\demo.txt","rt")) == NULL ){
        printf("Cannot open file, press any key to exit!");
        getch();
        exit(1);
    }

    //每次读取一个字节,直到读取完毕
    while( (ch=fgetc(fp)) != EOF ){
        putchar(ch);
    }
    putchar('\n');  //输出换行符
    fclose(fp);
    return 0;
}

2.EOF注意的问题.读取函数也可能出现EOF错误,此时我们不知道是函数错误,还是真正的到达文件结尾.

所以我们可以使用另外两个函数进行判断.

int feof ( FILE * fp );
int ferror ( FILE *fp );

例子:

#include<stdio.h>
int main(){
    FILE *fp;
    char ch;
  
    //如果文件不存在,给出提示并退出
    if( (fp=fopen("D:\\demo.txt","rt")) == NULL ){
        printf("Cannot open file, press any key to exit!");
        getch();
        exit(1);
    }

    //每次读取一个字节,直到读取完毕
    while( (ch=fgetc(fp)) != EOF ){
        putchar(ch);
    }
    putchar('\n');  //输出换行符

    if(ferror(fp)){
        puts("读取出错");
    }else{
        puts("读取成功");
    }

    fclose(fp);
    return 0;
}

五丶文件操作之文本操作,字符串操作

 相应的我们可以通过 fgetc和fputc进行字符操作.那么也可以进行字符串操作.一行一行的读.

char *fgets ( char *str, int n, FILE *fp );

参数1,, 数组.

参数2. 读取多少.

参数3.从哪里读取,

我们可以从fp(文件中) 读取参数2个大小.到数组str中.

例子:

#include <stdio.h>
#include <stdlib.h>
#define N 100
int main(){
    FILE *fp;
    char str[N+1];
    if( (fp=fopen("d:\\demo.txt","rt")) == NULL ){
        printf("Cannot open file, press any key to exit!\n");
        getch();
        exit(1);
    }
   
    while(fgets(str, N, fp) != NULL){
        printf("%s", str);
    }
    fclose(fp);
    system("pause");
    return 0;
}

字符串写入到文件.

int fputs( char *str, FILE *fp );

从数组中写入字符串到fp(文件中);

例子:

#include<stdio.h>
int main(){
    FILE *fp;
    char str[102] = {0}, strTemp[100];
    if( (fp=fopen("D:\\demo.txt", "at+")) == NULL ){
        printf("Cannot open file, press any key to exit!\n");
        getch();
        exit(1);
    }
    printf("Input a string:");
    gets(strTemp);
    strcat(str, "\n");
    strcat(str, strTemp);
    fputs(str, fp);
    fclose(fp);
    return 0;
}

六丶文件操作之二进制操作(数据块操作)

通常使用上面操作文本文件很简单.但是一般实际编程中都是数据块进行操作.

这样做可以避免很多问题.

数据块操作的函数

size_t fread ( void *ptr, size_t size, size_t count, FILE *fp );
size_t fwrite ( void * ptr, size_t size, size_t count, FILE *fp );

fread是读.fwrite是写.

参数1. ptr,可以是结构体,数组.或者变量.表示我要  读/写. 的内容. 如果是读.则此ptr则是保存数据.如果是写.则次ptr就是写出的数据.

参数2.写出数据的大小. 比如我们有一个变量要写出.我们这个变量的大小就可以定义一下.

参数3.表示我们要写出这个数据块的个数. 可以同时对一个变量/数组/结构体 写出或者读取多次.

参数4.文件指针,表示从哪个文件中读/写.

例子:

#include<stdio.h>
#define N 5
int main(){
    //从键盘输入的数据放入a,从文件读取的数据放入b
    int a[N], b[N];
    int i, size = sizeof(int);
    FILE *fp;

    if( (fp=fopen("D:\\demo.txt", "rb+")) == NULL ){
        printf("Cannot open file, press any key to exit!\n");
        getch();
        exit(1);
    }
  
    //从键盘输入数据 并保存到数组a
    for(i=0; i<N; i++){
        scanf("%d", &a[i]);
    }
    //将数组a的内容写入到文件
    fwrite(a, size, N, fp);
    //将文件中的位置指针重新定位到文件开头
    rewind(fp);
    //从文件读取内容并保存到数组b
    fread(b, size, N, fp);
    //在屏幕上显示数组b的内容
    for(i=0; i<N; i++){
        printf("%d ", b[i]);
    }
    printf("\n");

    fclose(fp);
    return 0;
}

 例子2:

#include<stdio.h>

#define N 2

struct stu{
    char name[10]; //姓名
    int num;  //学号
    int age;  //年龄
    float score;  //成绩
}boya[N], boyb[N], *pa, *pb;

int main(){
    FILE *fp;
    int i;
    pa = boya;
    pb = boyb;
    if( (fp=fopen("d:\\demo.txt", "wb+")) == NULL ){
        printf("Cannot open file, press any key to exit!\n");
        getch();
        exit(1);
    }

    //从键盘输入数据
    printf("Input data:\n");
    for(i=0; i<N; i++,pa++){
        scanf("%s %d %d %f",pa->name, &pa->num,&pa->age, &pa->score);
    }
    //将数组 boya 的数据写入文件
    fwrite(boya, sizeof(struct stu), N, fp);
    //将文件指针重置到文件开头
    rewind(fp);
    //从文件读取数据并保存到数据 boyb
    fread(boyb, sizeof(struct stu), N, fp);

    //输出数组 boyb 中的数据
    for(i=0; i<N; i++,pb++){
        printf("%s  %d  %d  %f\n", pb->name, pb->num, pb->age, pb->score);
    }
    fclose(fp);
    return 0;
}

七丶文件操作之格式化读写.

格式化读写就是从文件中.或者从内存中按照指定的格式进行读写.

主要用到两个函数.

int fscanf ( FILE *fp, char * format, ... );
int fprintf ( FILE *fp, char * format, ... );

函数1:

  从文件中 按照指定格式化读取.读取到...变量中.

FILE *fp;
int i, j;
char *str, ch;
fscanf(fp, "%d %s", &i, str);
fprintf(fp,"%d %c", j, ch);

函数2:

  fprintf同上.只不过作用相反.

操作例子:

#include<stdio.h>

#define N 2

struct stu{
    char name[10];
    int num;
    int age;
    float score;
} boya[N], boyb[N], *pa, *pb;

int main(){
    FILE *fp;
    int i;
    pa=boya;
    pb=boyb;
    if( (fp=fopen("D:\\demo.txt","wt+")) == NULL ){
        printf("Cannot open file, press any key exit!");
        getch();
        exit(1);
    }

    //从键盘读入数据,保存到boya
    printf("Input data:\n");
    for(i=0; i<N; i++,pa++){
        scanf("%s %d %d %f", pa->name, &pa->num, &pa->age, &pa->score);   
    }
    pa = boya;
    //将boya中的数据写入到文件
    for(i=0; i<N; i++,pa++){
        fprintf(fp,"%s %d %d %f\n", pa->name, pa->num, pa->age, pa->score);   
    }
    //重置文件指针
    rewind(fp);
    //从文件中读取数据,保存到boyb
    for(i=0; i<N; i++,pb++){
        fscanf(fp, "%s %d %d %f\n", pb->name, &pb->num, &pb->age, &pb->score);
    }
    pb=boyb;
    //将boyb中的数据输出到显示器
    for(i=0; i<N; i++,pb++){
        printf("%s  %d  %d  %f\n", pb->name, pb->num, pb->age, pb->score);
    }

    fclose(fp);
    return 0;
}

八丶文件操作之随机读写.

操作文件肯定避免不了我要读取指定文件内容或者写入指定文件内容.

提供了两个函数使用:

void rewind ( FILE *fp );  函数作用.将文件指针移动到文件头.
int fseek ( FILE *fp, long offset, int origin );函数作用将文件指针移动到指定偏移位置.
相对于origin
起始点    常量名    常量值
文件开头    SEEK_SET    0
当前位置    SEEK_CUR    1
文件末尾    SEEK_END    2

origin值如上.

例子: 移动文件指针到文件开头的位置.100字节

fseek(fp, 100, SEEK_SET);

 获取文件指针位置

long ftell(FILE *stream);

因为我们使用fseek,导致文件指针一直移动.不确定移动到哪里了.所以我们可以使用ftell来获取文件指针位置.

ftell函数的作用可以用来获取文件的大小.

例如:

fseek(fp,0L,SEEK_END); /* 定位到文件末尾 */
flen=ftell(fp); /* 得到文件大小 */

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏三杯水

Python Elasticsearch API操作ES集群

关键是DSL语法的编写涉及查询与聚合可以通过kibana的visualize或者devtool先测试出正确语法,然后结合python对列表、字典、除法、字符串等...

39420
来自专栏nummy

python click模块

python click模块用于编写命令行程序,它的目的是使用更少的代码,加快编写CLI程序的速度。

10530
来自专栏蓝天

C/C++常见gcc编译链接错误解决方法

用“-Wl,-Bstatic”指定链接静态库,使用“-Wl,-Bdynamic”指定链接共享库,使用示例: -Wl,-Bstatic -lmysq...

41730
来自专栏Albert陈凯

Hadoop数据分析平台实战——060深入理解MapReduce 01(案例)离线数据分析平台实战——060深入理解MapReduce 01(案例)

离线数据分析平台实战——060深入理解MapReduce 01(案例) 用户自定义数据类型 MapReduce中的数据类型至少有两种用途。 第一个用途,这些类...

31790
来自专栏马洪彪

Java设计模式(一)工厂模式

一、场景描述 仪器数据文件的格式包含Pdf、Word、Excel等多种,不同种格式的文件其数据的采集方式不同,因此定义仪器数据采集接口,并定义PDF、Excel...

42490
来自专栏友弟技术工作室

SQLAlchemy简单入门

SQlAlchemy简单使用 sqlalchemy介绍 SQLAlchemy的是Python的SQL工具包和对象关系映射器,让应用程序开发人员可以使用上SQL...

397100
来自专栏小勇DW3

Java设计模式-单例模式

作为对象的创建模式,单例模式确保其某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类。单例模式有以下特点:

13150
来自专栏Django Scrapy

python3 下调用zabbix api 获取多个机房的IP

根据工作的需要,需要查看监控中的所有ip,我们一共有三个机房,每个机房都部署了同样的zabbix监控 根据三个园区的 监控api的url 实现功能:不输入参数 ...

38050
来自专栏数据结构笔记

scrapy爬虫框架(四):scrapy中 yield使用详解

MySQL下载:点我 python MySQL驱动下载:pymysql(pyMySql,直接用pip方式安装)

13620
来自专栏deepcc

jquery插件开发模板

375100

扫码关注云+社区

领取腾讯云代金券