C语言---文件操作

一 ,先来了解一下什么叫流??
计算机中大量设备都与I/O有关。CD驱动器,软盘硬盘驱动器,网络 连接,通信接口,视频适配器就是很常见的外设。每一种外设都有不同的特性和操作协议。OS负责这些不同设备的通信细节,并向用户提供一个更为简单的统一的I/O接口。而ANSI C进一步对I/O的概念进行了抽象。就C程序而言,所谓的I/O操作就是简单从程序移进,移出字节的事情,这种字节流就叫做 流。文件和设备的操作都是基于流的操作。
流分为两种:文本流 和 二进制流。

文本流在不同的系统中实现不一样
二进制流中的字节是安装程序编写的形式写入到文件和设备中,而且完全根据从文件或设备中读取的形式读入到程序。

二,什么是文件呢
文件是一段数据的集合,这些数据可以是有规则的,也可以是无序的集合。在stdio.h有一个非常重要的东西,文件指针,每个文件都会在内存中开辟一块空间,用于存放文件的相关信息,这些信息保存在一个结构体变量中,FILE *pIn,点击FILE转到定义看一下,这个结构体在VS编译器中的定义如下:

struct _iobuf {
        char *_ptr;  //指向buffer中第一个未读的字节
        int   _cnt;  //记录剩余的未读字节的个数
        char *_base;//文件的缓冲
        int   _flag;//打开文件的属性
        int   _file;//获取文件描述
        int   _charbuf;//单字节的缓冲,即缓冲大小仅为1个字节,如果为单字节缓冲,_base将无效
        int   _bufsiz;//记录这个缓冲大小
        char *_tmpfname;//
        };
typedef struct _iobuf FILE;
FILE是一个数据结构,用于访问一个流。,如果你激活了几个流,每个流都会对应一个FILE结构

我们来看一下如何打开一个文件
FILE *fopen( const char *filename, const char *mode );

  • filename是文件名,这里写的是文件的路径。
  • mode是打开模式
    下图是文件的使用方式:
    这里写图片描述
    这里写图片描述
    例如:
int main()
{
    FILE* pf;
    pf = fopen("myfile.txt", "w");
    if (pf != NULL)
    {
        fputs("fopen example", pf);
        fclose(pf);
        pf=NULL;
    }
    system("pause");
    return 0;
}

注意的一些点:
文件判断是否打开成功;
关闭文件;
文件指针置空
关闭文件:
函数原型:int fclose( FILE *stream );
用于关闭流。如:fclose(pf);

对于每一个C程序而言,至少打开三个流:
标准输入(stdin),标准输出(stdout),标准错误(stderr),他们都是一个指向FILE结构的指针。
通常:标准输入为:键盘设备;标准输出:终端或屏幕。
stderr函数用法:
有没有换行它都会输出结果,而stdout 标准输出在默认情况下,stdout是行缓冲的,它的输出会放在一个buffer里面,只有到换行的时候,才会输出到屏幕。

int main()
{
    FILE*pf = fopen("unexistfile.dat", "r");

    if (pf == NULL)
    {
        fprintf(stderr, "open error");
    }
    else
    {
        fclose(pf);
    }
    system("pause");
    return 0;
}

这里写图片描述

三,

I/O函数:


I/O函数有三种方式:
单个字符,文本行,二进制数据。以下是几种输入输出函数:

功能函数名适用于
字符输入函数getchar标准输入流
字符输出函数putchar标准输出流
字符输入函数fgetc, getc所有输入流
字符输出函数fputc, putc所有输出流
文本行输入函数fgets,gets所有输入流
文本行输出函数fputs,puts所有输出流
格式化输入函数scanf标准输入流
格式化输出函数printf标准输出流
格式化输入函数fscanf所有输入流
格式化输出函数fprintf所有输出流
二进制输入fread文件
二进制输出fwrite文件
  1. fgetc(getc)和fputc(putc)

fgetc(getc)用于输入一个字符。从指定的文件中获取字符,并作为返回值返回。
函数原型:int fgetc( FILE *stream );
ch = fgetc(pf);
下例是把myfile.txt文件中的内容输出到标准输出流上。

    char ch = 0;
    FILE* pf = fopen("myfile.txt", "r");
    if (pf == NULL)
    {
        perror("error opening file");
        exit(0);
    }
    while (ch != EOF)
    {
        ch = fgetc(pf);
        putc(ch, stdout);
    }
    fclose(pf);

fputc(putc)
用于输出一个字符。下例是把从键盘输入的信息输出到myfile.txt文件中,以’$’作为结束符。
函数原型:int fputc( int c, FILE *stream );

char ch;
    FILE* pf = fopen("myfile.txt", "w");
    if (pf == NULL)
    {
        perror("error opening file");
        exit(0);
    }
    ch = getchar();
    while (ch != '$')
    {
        fputc(ch, pf);
        ch = getchar();
    }
    fclose(pf);

2.fgets和fputs函数

fgets函数
用于文本行的输入
函数原型:char *fgets( char *string, int n, FILE *stream );
fgets(str,n,pf);从pf所指文件中读入n-1个字符放入以str为起始地址的空间中;遇到换行或文件结束符则结束,返回值是str。

    char buf[10] = { 0 };
    FILE *pf = fopen("myfile.txt", "r");
    if (pf == NULL)
    {
        perror("open file for reading");
        exit(EXIT_FAILURE);
    }
    fgets(buf, 9, stdin);
    fputs(buf, stdout);
    fclose(pf);

fputs函数
是把文本行输出到文件中
函数原型:int fputs( const char *string, FILE *stream );
fputs(str,pf);把str所指向的地址中的内容输出到pf所指向的文件中。

3.fscanf和fprintf函数
fscanf函数
是格式化输入函数,和printf相似,区别在于这个函数既使用文件流,又适用于标准输入流。
函数原型:int fscanf( FILE *stream, const char *format [, argument ]… );

  fscanf(pf,"%d,%d",&a,&b);
  fscanf(stdin,"%d,%d",&a,&b);
    char ch = 0;
    int num = 0;
    char arr[10] = { 0 };
    fscanf(stdin, "%s %d %c", arr, &num, &ch);
    fprintf(stdout,"%s %d %c\n", arr, num, ch);

fprintf函数
格式化输出函数。
函数原型:int fprintf( FILE *stream, const char *format [, argument ]…);

  fprintf(pf,"%d,%d",a,b);
  fprintf(stdout,"%d,%d",a,b);

4.sprintf()和sscanf()函数
int sprintf( char *buffer, const char *format [, argument] … );
int sscanf( const char *buffer, const char *format [, argument ] … );
返回值字符串的长度。
可以把格式化数据转换成字符串,用sprintf()函数
也可以把字符串转换成格式化数据,用sscanf()函数
如下例

struct S
{
    char name[10];
    int age;
    float f;
};
int main()
{
    //struct S stu = { "zhangsan", 20, 1.5f };
    //char buf[100] = { 0 };
    //sprintf(buf, "%s %d %f", stu.name, stu.age, stu.f);//字符串形式放入buf中
    //printf("%s\n", buf);


    struct S tmp = { 0 };
    struct S stu = { "zhangsan", 20, 1.5f };
    char buf[100] = { 0 };
    sprintf(buf, "%s %d %f", stu.name, stu.age, stu.f);//字符串形式放入buf中
    sscanf(buf, "%s %d %f", tmp.name, &(tmp.age),&(tmp.f));//从buf中拿出字符串转换成格式化数据
    printf("%s %d %f\n", tmp.name, tmp.age, tmp.f);//打印结构体tmp的成员变量的值

    system("pause");
    return 0;
}

5.fread和fwrite函数

fwrite函数
以二进制方式输出
函数原型:size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
fwrite(buf, sizeof(char), sizeof(buf), pf);

  • 从buf是一个指针,是要获取数据的地址。
  • size个 单位:字节
  • count最多写多少个
  • pf写入到目标文件

    例如这个题是把结构体信息写入到myfile.txt这个文件中。

struct S
{
    char name[10];
    int age;
    float f;
};
int main()
{
    struct S stu = { "zhangsan", 20, 1.2f };
    FILE* pf = fopen("myfile.txt", "w");
    if (pf == NULL)
    {
        perror("error opening file");
        exit(EXIT_FAILURE);
    }
    fwrite(&stu, sizeof(struct S), 1, pf);//二进制的形式写进去
    fclose(pf);
    pf = NULL;
    system("pause");
    return 0;
}

fread函数:
函数原型:size_t fread( void *buffer, size_t size, size_t count, FILE *stream );

  • fread(buf,size,count,pf);

这个题是把pf 所指向的文件中的信息读入到结构体中。

struct S
{
    char name[10];
    int age;
    float f;
};
int main()
{
    struct S stu = { 0};
    FILE* pf = fopen("myfile.dat", "r");
    if (pf == NULL)
    {
        perror("error opening file");
        exit(EXIT_FAILURE);
    }
    fread(&stu, sizeof(struct S), 1, pf);
    printf("%s %d %f\n", stu.name, stu.age, stu.f);
    fclose(pf);
    pf = NULL;
    system("pause");
    return 0;
}

6.fseek函数
fseek是文件定位函数,用来移到文件指针到指定的位置上,从此位置开始进行读写。

函数原型: int fseek( FILE *pf, long offset, int origin );

  • pf文件指针
  • offset偏移量,单位字节
  • origin是起始位置,指定位移量是从哪个位置开始偏移

    origin这个参数有三种选项:

  • SEEK_CUR—文件指针的当前位置

  • SEEK_END—文件结尾
  • SEEK_SET—文件开始

fseek(pf,-1,SEEK_CUR); 从当前位置向前偏移一个字节
fseek(pf,0,SEEK_SET); 从起始位置开始
fseek(pf,4,SEEK_SET); 从起始位置向后偏移4个字节
7. ftell函数
用来获取文件指针的当前位置,成功返回当前位置指针相对文件开始位置的字节数失败返回-1L。
函数原型:long ftell( FILE *stream );
可以用来测试一个文件的长度:

long n;
fseek(pf,0,SEEK_END);
n=ftell(pf);

8.rewind函数
功能是 使文件指针回到文件开头。
函数原型:void rewind( FILE *stream );
rewind(pf);

9.clearerr函数
功能是 重置文件流的错误指示。
函数原型:void clearerr( FILE *stream );

10.feof函数
测试文件流是否读到了文件尾
函数原型:int feof( FILE *stream );

  • 调用成功返回一个非零值,失败返回0。
  • 返回非零值说明已经到达文件尾。
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值