前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言第十二讲,文件操作.

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

作者头像
IBinary
发布2018-07-31 16:32:27
1.8K0
发布2018-07-31 16:32:27
举报
文章被收录于专栏:逆向技术逆向技术

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

一丶文件操作概述

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

 操作文件的步骤

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

二丶文件流的概述.

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

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

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

三丶文件的打开和关闭.

1.操作原型.

代码语言:javascript
复制
FILE *fopen(char *filename, char *mode);

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

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

例子:

代码语言:javascript
复制
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+

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

文件的关闭

代码语言:javascript
复制
int fclose(FILE *fp)
例如:
fclose(fp);

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

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

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

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

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

例子:

代码语言:javascript
复制
#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错误,此时我们不知道是函数错误,还是真正的到达文件结尾.

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

代码语言:javascript
复制
int feof ( FILE * fp );
int ferror ( FILE *fp );

例子:

代码语言:javascript
复制
#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进行字符操作.那么也可以进行字符串操作.一行一行的读.

代码语言:javascript
复制
char *fgets ( char *str, int n, FILE *fp );

参数1,, 数组.

参数2. 读取多少.

参数3.从哪里读取,

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

例子:

代码语言:javascript
复制
#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;
}

字符串写入到文件.

代码语言:javascript
复制
int fputs( char *str, FILE *fp );

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

例子:

代码语言:javascript
复制
#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;
}

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

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

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

数据块操作的函数

代码语言:javascript
复制
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.文件指针,表示从哪个文件中读/写.

例子:

代码语言:javascript
复制
#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:

代码语言:javascript
复制
#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;
}

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

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

主要用到两个函数.

代码语言:javascript
复制
int fscanf ( FILE *fp, char * format, ... );
int fprintf ( FILE *fp, char * format, ... );

函数1:

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

代码语言:javascript
复制
FILE *fp;
int i, j;
char *str, ch;
fscanf(fp, "%d %s", &i, str);
fprintf(fp,"%d %c", j, ch);

函数2:

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

操作例子:

代码语言:javascript
复制
#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;
}

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

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

提供了两个函数使用:

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

origin值如上.

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

代码语言:javascript
复制
fseek(fp, 100, SEEK_SET);

 获取文件指针位置

代码语言:javascript
复制
long ftell(FILE *stream);

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

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

例如:

代码语言:javascript
复制
fseek(fp,0L,SEEK_END); /* 定位到文件末尾 */
flen=ftell(fp); /* 得到文件大小 */
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-06-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  •        C语言第十二讲,文件操作.
    • 一丶文件操作概述
      • 二丶文件流的概述.
        • 三丶文件的打开和关闭.
          • 1.操作原型.
          • 四丶文件操作之文本操作,字符操作.
        • 五丶文件操作之文本操作,字符串操作
          • 六丶文件操作之二进制操作(数据块操作)
            • 七丶文件操作之格式化读写.
              • 八丶文件操作之随机读写.
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档