C语言文件

文件基础知识

对象

  1. 对于操作系统而言,所有东西即是文件。

文件分类

  1. 文件分为数据文件、程序文件。
  2. 数据文件文件分为:ACSII文件(文本文件)、二进制文件。文本文件:以ACSII字符作为单个数据内容。
  3. 数据在内存中以二进制储存,不加转化储存到外村(磁盘)则是内存文件的映像文件。文本文件进行了转化。
  4. 系统定义好了一个文件结构体FILE类型,一般用来定义文件指针,来访问文件,系统根据文件,自动写入相关的信息。注意:文件指针指向的是内存区域文件信息(FILE结构体的第一个元素)的开头地址。

文件的打开和关闭函数

  • 打开文件:指的是为文件建立信息区(存放文件的信息)和文件缓冲区(存储暂时输入输出的数据)
  • 打开文件函数 FILE *fopen("filename","r、r+、rb、w+")
  • "filename"=字符数组指针 or文件path ,同一目录下不用加path。
#include <stdio.h>
#include <cstdlib>

int main()
{
    FILE *fp;
    if(fopen("1.txt","rb")==NULL)
    {
        printf("error");
        exit(0);
    }//判断是否是空指针
  //内存大小不够会导致w文件错误,返回空指针
  //
    printf("%d",16|1);
    return 0;
}
  • 关闭文件:撤销文件信息区域,和文件缓存区域
  • 关闭文件函数FILE *fclose(fp) fp为文件指针。
  • 如果不关闭文件,且文件缓冲区没有满,在这时结束程序会导致文件数据丢失。所以要先关闭文件。

顺序读写文件数据

  • 注意:计算机输入ASCII字符时候,遇到回车换行符号时,输出到终端转化为回车、换行两个符号。以二进制输入不会。

相关函数

  • 从指定文件读入单个字符函数fgetc、读入字符串函数fgets
```int fgetc(
   FILE *stream
);//成功返回1,否则返回EOF。文件指针可以是stdin

wint_t fgetwc(
   FILE *stream
);

char * fgets ( char * str, int num, FILE * stream );//需要提前定义一个字符数组。

  • 输出单个字符到指定文件函数fputc、输出字符串到指定文件函数fputs
int fputc ( char c, FILE * stream );
int fputs (string c | char * c, FILE *stream)
也就是可以是字符常量、字符串常量,或者就是相应的指针。

实例

操作实例1:

#include <stdio.h>
#include <cstdlib>
#include <unistd.h>

int main() {
    FILE *fp;
    char ch;
    char name[10];
#ifdef debug
    scanf("%s", name);
#endif
    if ((fp = fopen("t1.txt", "r")) == NULL) {
        fprintf(stderr, "error");
        exit(0);
    }
//    ch = getchar();//接受最后输入得回车符
//    ch = getchar();
#ifdef debug
    while (ch != '#') {
        fputc(ch, fp);
        //将一个字符输出到子盘文件上,如果输出失败,则返回EOF,值为-1.
        ch = getchar();
    }
    fclose(fp);//关闭文件
#endif
    char name1[10];
    FILE *fp1;
    scanf("%s",name1);
    if((fp1=fopen(name1,"w"))==NULL)
    {
        fprintf(stderr,"error");
        exit(EXIT_SUCCESS);
    }
    ch=getchar();
    while(!feof(fp))
    {
//      ifeof(fp)遇到文件结束标识符就返回0,否则返回一个不同于0的值;随着文件读写位置标记来进 行识别
//      int feof ( File * Stream );
        fputc(fgetc(fp),fp1);
        //从指定的文件按照顺序读入一个字符。

        putchar(fgetc(fp));
    }
    fclose(fp1);
    fclose(fp);
    return 0;
}

操作实例2:

#include <stdio.h>
#include <cstdlib>
#include <unistd.h>

int main() {
    FILE *fp;
    char ch;
    char name[10];
#ifdef debug
    scanf("%s", name);
#endif
    if ((fp = fopen("t1.txt", "r")) == NULL) {
        fprintf(stderr, "error");
        exit(0);
    }
//    ch = getchar();//接受最后输入得回车符
//    ch = getchar();
#ifdef debug
    while (ch != '#') {
        fputc(ch, fp);
        //将一个字符输出到子盘文件上,如果输出失败,则返回EOF,值为-1。
        ch = getchar();
    }
    fclose(fp);//关闭文件
#endif
    char name1[10];
    FILE *fp1;
    scanf("%s",name1);
    if((fp1=fopen(name1,"w"))==NULL)
    {
        fprintf(stderr,"error");
        exit(EXIT_SUCCESS);
    }
    ch=getchar();
    char str[15];
    fputs(fgets(str,4,fp),fp1);
  //全部读入只需要把4给的很大
    fclose(fp1);
    fclose(fp);
    return 0;
}

操作实例3:

/* fputs example */
#include <stdio.h>

int main ()
{
   FILE * pFile;
   char sentence [256];

   printf ("Enter sentence to append: ");
   fgets (sentence,256,stdin);
   pFile = fopen ("mylog.txt","a");
  //若是以r打开文件则不能读入从终端输入的字符,stdin标准输入流
   fputs (sentence,pFile);
   fclose (pFile);
   return 0;
}

用格式化等的方式读写文件

int fprintf ( FILE * stream, const char * format, ... );
fprintf(fp,"%d,%s,%f",12,"asd",12.963);
//将这些输出列表元输出到文件
int fscanf ( FILE * stream, const char * format, ... );
将fp对应文件的两个整型值赋给i,j。
fscanf(fp,"%d ,%d,",&i,&j)
//缺点:由于fscanf要先从文件读入ASCII码数据时,要先在内存中进行转化二进制,然后才能保存到对饮的内存变量之中,所以耗时较大;
//fprintf在输出ASCII码数据到文件时,同样要先在内存中间转化为二进制数据,故耗时也很大。

操作实例

#include <iostream>

using namespace std;

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *fp;
    if ((fp = fopen("t1.txt", "w+")) == NULL) {
        printf("d");
    }
    struct stu
    {
        int id;
        char name[];
    }en;
    fprintf(fp,"%d,%s",56,"sdji");
    fscanf(fp,"%d,%s",&en.id,en.name);
    printf("%d",en.id);
    return 0;
}

用二进制方式向文件读写一组数据

  • 读写的时候是以二进制形式进行的,故fopen打开文件要以"rb,wb,rb+,wb+"
  • fread 函数
//函数格式
size_int fread ( void * ptr, size_t size, size_t count, FILE * stream );

//ptr表示从文件读入的数据   的起始储存地址(存到哪里去)。
//函数为int整型函数,成功读入返回值为cout的值,即为读入数据项的个数。size读写的单个数据占多少个字节,cout表示读写多少个字节为size的数据。
  • fwrite函数
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
//ptr要输入文件的数据的初始地址(哪里的数据要向文件输入)。其他同上。
  • 操作实例

#include <iostream>
#include <stdlib.h>
#include <stdio.h>

using namespace std;
#define SIZE 3
#define debug

int main() {
    typedef struct student {
        int id;
        char name[10];
    } stu;
    stu s[SIZE];
    for (int i = 0; i < SIZE; i++) {
        scanf("%d%s", &s[i].id, s[i].name);
    }
    FILE *fp;
    if ((fp = fopen("t1.txt", "rb+")) == NULL) {
        fprintf(stderr, "err");
        exit(0);
    }
    for (int i = 0; i < SIZE; i++) {
        if (fwrite(&s[i], sizeof(stu), 1, fp) != 1)
            printf("d\n");
    }
    fclose(fp);
    FILE *fp1;
    fp1 = fopen("t1.txt", "rb+");
    stu ren[3];
#ifdef debug
    for (int i = 0; i < SIZE; i++) {
        fread(&ren[i], sizeof(stu), 1, fp1);
        printf("%d %s\n", ren[i].id, ren[i].name);
    }
    fclose(fp1);
#endif
    return 0;
}

二进制输出、读入数据注意事项

  1. //向文件输出那种类型数据,则读出数据的时候也应该定义相应类型的变量来接入
  2. fwrit文件(将数据写入文件以后)以后一定要先关闭文件,然后才用fread读入文件里面的数据。对于一个空白文件来说,写入数据以后文件读写标记移动到文件末尾(文件结束标志),此时将文件的数据读出,则是从文件末尾读出,但是后面是空白,所以会出现错误。

随机读写文件数据

  • rewind函数
//void rewind ( FILE * stream );
//函数将文件的读写表示符移动到文件初始位置。

#include <iostream>
#include <stdlib.h>
#include <stdio.h>

using namespace std;
#define SIZE 3
#define debug

int main() {
    typedef struct student {
        int id;
        char name[10];
    } stu;
    stu s[SIZE];
    for (int i = 0; i < SIZE; i++) {
        scanf("%d%s", &s[i].id, s[i].name);
    }
    FILE *fp;
    if ((fp = fopen("t1.txt", "rb+")) == NULL) {
        fprintf(stderr, "err");
        exit(0);
    }
    for (int i = 0; i < SIZE; i++) {
        if (fwrite(&s[i], sizeof(stu), 1, fp) != 1)
            printf("d\n");
    }
    rewind(fp);
    stu ren[3];
#ifdef debug
    for (int i = 0; i < SIZE; i++) {
        fread(&ren[i], sizeof(stu), 1, fp);
        printf("%d %s\n", ren[i].id, ren[i].name);
    }
    fclose(fp);
#endif
    return 0;
}

  • fseek函数
int fseek ( FILE * stream, long int offset, int origin );
//origin 的值为0,1,2;其中0表示文件开头的位置,1表示文件表示符当前的位置,2表示文件末尾行。
//offset表示标识符移动的单位距离,值为正表示向前移动看,值为负表示向后移动。


//前面是定义了一个包含了两个元素的结构体,并且读入了三个结构体变量数据给fp指向的文件
    rewind(fp);
    stu ren[3];
    fseek(fp,sizeof(stu),1);
#ifdef debug
    if(fread(&ren[1].id,4,1,fp)!=1)
        printf("%s","cao");
    printf("%d",ren[1].id);
    fclose(fp);
#endif
    return 0;
  • ferror、clearerr函数
int ferror ( FILE * stream );
//当读取文件数据,或者写入数据到文件没有问题的时候函数值返回为0;否则返回一个非零值。

注意:对于同一文件而言每次读取操作都会产生一个ferror函数值,应该及时检验

void clearerr ( FILE * stream );
清除ferror的函数值,避免上一步读写操作的ferror值影响到下一次读写是否错误的判断。

fscanf,fprintf,fread,fwrite函数返回值

  • 这四个函数成功执行返回写入文件\从文件读出 的数据个数,否则返回EOF。
  • fputc、fputs成功执行返回0,否则返回EOF
  • fgetc成功执行返回字符首地址,否则返回NULL 、fgets成功执行返回数组首地址,否则返回NULL
全部评论

相关推荐

面试摇了我吧:啊哈哈面试提前五个小时发,点击不能参加就是放弃
点赞 评论 收藏
分享
10-28 11:04
已编辑
美团_后端实习生(实习员工)
一个2人:我说几个点吧,你的实习经历写的让人觉得毫无含金量,你没有挖掘你需求里的 亮点, 让人觉得你不仅打杂还摆烂。然后你的简历太长了🤣你这个实习经历看完,估计没几个人愿意接着看下去, sdk, 索引这种东西单拎出来说太顶真了兄弟,好好优化下简历吧
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务