C语言——文件

简介: 文件

文件的基本操作

前言

文件是当今计算机系统不可或缺的部分。文件用于存储程序,文档,数据,书信,表格,图形,照片,等其它种类的信息,作为程序员,必须会编写创建文件和从文件中读写数据。


什么是文件?

文件通常是指在磁盘或固态是的一段已经命名的缓冲区,例如我们经常使用的stdio.h就是一个文件,c语言将文件看成一段连续的字节,每个字节都可被单独读输,c提供了两种模式:文本模式和二进制模式。

一、如何打开文件和关闭文件

打开文件

在c语言中我们一般利用fopen函数来打开文件,该函数声明在<stdio.h>库中。调用该函数的一般形式:

FILE*fp;

fp=fopen(char*str1, "str2");

其中str1指向一个字符串,该字符串为该文件的文件名(即路径),第二个参数为c语言规定的模式字符串。详情如下:这里请注意,如果使用w模式打开一个现有文件,该文件的内容会被删除。程序成功打开文件后,fopen函数返回文件指针,其他I/O函数可以使用这个指针指定该文件,即上述代码中的fp,FILE是c语言的一种结构体,它的定义在stdio.h库中。其中包含了缓冲区信息等,这里不多赘述。若是我们打开文件失败,这里fopen()函数会返回一个空指针。

关闭文件

我们在对文件进行完操作之后,要关闭文件,防止文件内容被破坏,在c语言中我们一般用fclose()函数关闭文件,形式如下:

fclose(fp);

其中fp为文件指针,必要时会刷新缓冲区,当磁盘已满,移动硬盘被拔出或者出现I/O错误时文件会关闭失败,所以对于比较正式的程序我们应该检查文件是否关闭,当文件成功关闭时fclose函数返回0,否则返回EOF(这里eof为文件结尾)。判断代码如下:

if (fclose(fp) !=0) {

   printf("Error in closing file %s\n", str1);

}

二、文件的读写操作

1.输入输出字符

在c语言中我们利用getc()和putc()函数进行文件里字符的输入和输出,语法如下所示:

ch=getc(fp);

putc(ch, fp);

getc函数是读取文件中的一个字符赋给ch。putc函数是将ch写入文件中。

2.输入输出字符串:

在文件中我们要进行字符串的输入和输出可以利用fgets函数和fputs函数,语法如下所示:

fgets(buf, stlen, fp);

fgets函数的第一个参数和gets函数相同表示存储输入的地址(如上述代码中的buf是一个char型数组的名称),第二个参数是一个整数,表示带输入字符串的大小,最后一个参数为文件指针。fgets函数读取输入直到第一个换行符的后面,或者读到文件的末尾——EOF,或者读取到stlen-1个字符,然后fgets函数在末尾添加一个空字符使之成为一个字符串,故我们读取的字符串长度为字符数加上一个空字符。 注意,如果fgets函数在读到字符上限之前已经读完一行,它为将换行符放到空字符前面。fgets在遇见eof即文件结尾时会返回null

fputs(buf, fp)

fputs函数的两个参数实际意义与fgets相同,它的作用是将字符串写入指定的文件中,其中由于fgets函数会保留换行符,所以fputs函数不会像puts函数一样自动添加换行符。

3.格式化输入与输出

文件的格式化输入与输出函数为fscanf,fprintf函数其工作方式与scanf,printf类似。语法如下所示:

fprintf(fp, "%s", str1);

fscanf(fp, "%d", &a);

4.文件读写移动操作

在我们对文件进行读取时,经常需要改变读取的位置,在c语言中有两个函数可以便于我们进行这种操作,

  1. ftell函数:用来取文件当前位置。其一般形式为:long n;n = ftell(fp);它的返回值时一个长整型,表示当前的读写位置(从文件开始处到现在的字节数),调用正确返回当前读写位置,错误返回-1L.
  2. fseek函数fseek函数用来改变文件指针的当前位置。其一般形式为:fseek(fp,offset,from);offset:位移量,类型为long型,表示以from为起点移动的量相对值(字节数)。from:移动的起始位置。from是一种模式,如下所示:

文件的应用——倒序打印文件中的字符

例如我们在文本中输入hello world,输出结果为:dlrow olleh。

#include<stdio.h>

#include<stdlib.h>

#define SLEN 81

intmain(void) {

   charfile[SLEN];

   charch;

   FILE*fp;

   longcount, last;

   puts ("Enter the name of the file to be processed:");

   scanf("%80s",file);

   if ((fp=fopen(file, "r")) ==NULL) {      //以只读的方式打开文件

       printf("不存在文件%s\n", file);

       exit(1);

   }

   fseek(fp, 0L, SEEK_END);                    //定位到文件末尾

   last=ftell(fp);                           //获得从文件开始到现在的字节数

   for (count=1L; count<=last; count++) {

       fseek(fp, -count, SEEK_END);            //回退

       ch=getc(fp);

       if (ch!='EOF'&&ch!='r') {

           putchar(ch);

       }

   }

   printf("\n");

   fclose(fp);

   return0;

}

文件的读写

一:打开文件句柄

//参数1:文件路径

//参数2:文件打开模式

函数执行成功返回文件流指针,错误返回NULL。

FILE *fopen(const char *path, const char *mode);


模式        操作        区别          文件要求

r            读       从文件头开始     文件需存在

r+          读写      从文件头开始     文件需存在

w           写       从文件头开始     文件不存在则创建,存在则清空

w+         读写     从文件头开始     文件不存在则创建,存在则清空

a           写      从文件尾开始     文件不存在进行创建,存在则追加

a+         读写     从文件头读取,从文件尾写入    文件不存在进行创建,存在则追加


代码示例:

#include <stdio.h>


int main()

{

   FILE *p = fopen("/tmp/1.txt", "r");

   if(p == NULL)

   {

       printf("open error!\n");

       return 0;

   }

   fclose(p);

   return 0;

}


二:文件关闭

//参数1:文件流

int fclose(FILE *fp);


三:文件写入

1、字符写入:fputc();

//参数1:写入的字符

//参数2:文件流

//作用:将单个字符写入到文件中

//返回值:成功时,返回写入字符的ascii码值,错误返回EOF(-1)

int fputc(int c, FILE *stream);


示例:

#include <stdio.h>

#include <string.h>


int main()

{

   FILE *file = fopen("/opt/admin/tmp/1.txt", "w");

   if(file == NULL)

   {

       printf("open error!\n");

       return 0;

   }

   char name[] = "hello world!";

   int i;

   for(i = 0; i < strlen(name); i++)

   {

       fputc(name[i], file);

   }

   fputc('\n', file);

   fclose(file);

   return 0;

}


2、字符串写入:fputs();

//参数1:写入的字符串

//参数2:文件流

//作用:将字符串写入文件中

//返回值:返回一个非负值,如果发生错误则返回 EOF(-1)。

int fputs(const char *s, FILE *stream);


示例:

#include <stdio.h>

#include <string.h>


int main()

{

   FILE *file = fopen("/opt/admin/tmp/1.txt", "w");

   if(file == NULL)

   {

       printf("open error!\n");

       return 0;

   }

   char name[] = "hello world!\n";

   fputs(name, file);

   fclose(file);

   return 0;

}


3、数据块写入:fwrite();

//参数1:要获取的数据的地址

//参数2:要写入内容的单字节数

//参数3:要写入size字节的数据项的个数

//参数4:目标文件指针

//返回值:返回实际写入的数据块的数目

//作用:向文件写入数据块,以二进制形式对文件进行操作,不局限于文本文件。

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);


示例:

#include <stdio.h>

#include <string.h>


int main()

{

   FILE *file = fopen("/opt/admin/tmp/1.txt", "wb+");

   if(file == NULL)

   {

       printf("open error!\n");

       return 0;

   }

   char name[] = "hello world!\n";

   fwrite(name, strlen(name), 1, file);

   fclose(file);

   return 0;

}


4、格式化写入:fprintf();

//参数1:目标文件指针

//参数2:指定的格式控制字符串

//参数3:各种输出项,与格式控制字符串中的字段一起写到文件中

//返回值:执行成功返回实际写入文件的字符个数;执行失败,返回负数

//作用:用来将输出项按指定的格式写入到指定的文本文件中。

int fprintf(FILE *stream, const char *format, ...);


示例:

#include <stdio.h>

#include <string.h>


int main()

{

   FILE *file = fopen("/opt/admin/tmp/1.txt", "wb+");

   if(file == NULL)

   {

       printf("open error!\n");

       return 0;

   }

   char name[] = "hello world!\n";

   fprintf(file, "this is %s\n", name);

   fclose(file);

   return 0;

}

四:文件读取

1、字符读取:fgetc()

//参数1:目标文件指针

//返回值:执行成功返回读取的字符,读取错误或者遇到结束标志EOF,返回EOF

//作用:从指定的文件中读取一个字符

int fgetc(FILE *stream);


示例:

#include <stdio.h>

#include <string.h>


int main()

{

   FILE *file = fopen("./1.txt", "r");

   if(file == NULL)

   {

       printf("open error!\n");

       return 0;

   }

   char c;

   while((c = fgetc(file)) != EOF)

   {

       printf("%c", c);

   }

   fclose(file);

   return 0;

}

2、字符串读取:fgets()

//参数1:存储读取的数据

//参数2:存储数据的大小

//参数3:要读取的文件流

//返回值:成功则返回读取的buf,失败则返回NULL,这是,buf中的数据不确定

//作用:读取指定场长度的字符串存到字符数组中。每次只读取一行,每次最多读bufsize-1个字符(第bufsize个字符赋'\0')

char *fgets(char *buf, int bufsize, FILE *stream);


示例:

#include <stdio.h>

#include <string.h>


int main()

{

   FILE *file = fopen("./1.txt", "r");

   if(file == NULL)

   {

       printf("open error!\n");

       return 0;

   }

   char buf[1024] = {0};

   while(fgets(buf, 1024, file) != NULL)

   {

       printf("%s", buf);

   }

   fclose(file);

   return 0;

}

3、数据块读取:fread()

//参数1:存储读取的数据

//参数2:要读取的每个数据项的字节数

//参数3:要读取的数据项的个数

//参数4:读取的文件流

//返回值:返回真实读取的数据项count数,错误时返回0

//作用:一次读取文件中由若干个数据项组成的数据块,数据块的大小取决于数据项的大小和数据项的个数。

size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;


示例:

#include <stdio.h>

#include <string.h>


int main()

{

   FILE *file = fopen("./test", "r");

   if(file == NULL)

   {

       printf("open error!\n");

       return 0;

   }

   char buf[102400] = {0};

   fread(buf, 1024, 100, file);

   printf("%s", buf);

   fclose(file);

   return 0;

}


4、格式化读取:fscanf()

//参数1:读取的文件流

//参数2:读取的字符格式

//参数3:读取的各个输入项

//返回值:成功则返回读入的参数个数,失败返回EOF

//作用:根据数据格式format从文件流中读取数据,遇到空格或换行结束。

int fscanf(FILEstream,const charformat,[argument...]);

示例:

#include <stdio.h>

#include <string.h>


int main()

{

   FILE *file = fopen("./1.txt", "r");

   if(file == NULL)

   {

       printf("open error!\n");

       return 0;

   }

   char buf[1024] = {0};

   fscanf(file, "%s", buf);

   printf("%s\n", buf);

   fclose(file);

   return 0;

}


五:文件读写结合

1、fgetc()与fputc()结合使用

//以字符格式读取文件,再以字符格式写入文件,适用于文本文件

示例:

#include <stdio.h>

#include <string.h>


int main()

{

   FILE *file = fopen("./1.txt", "r");

   if(file == NULL)

   {

       printf("open error!\n");

       return 0;

   }

   FILE *fp = fopen("./2.txt", "w");

   char c;

   while( (c = fgetc(file)) != EOF )

   {

       fputc(c, fp);

   }

   fclose(file);

   fclose(fp);

   return 0;

}


2、fgets()与fputs()结合使用

//从文件中按行读取字符串,再以字符串写入文件,适用于文本文件,优点是按行读取很方便

示例:

#include <stdio.h>

#include <string.h>


int main()

{

   FILE *file = fopen("./1.txt", "r");

   if(file == NULL)

   {

       printf("open error!\n");

       return 0;

   }

   FILE *fp = fopen("./2.txt", "w");

   char buf[1024] = {0};

   while(fgets(buf, 1024, file) != NULL)

   {

       fputs(buf, fp);

   }

   fclose(file);

   fclose(fp);

   return 0;

}


3、fread()与fwrite()结合使用

//以数据块格式读取,再以数据块格式写入到文件中,可以读取二进制文件,优点是读取二进制文件使用

示例:

#include <stdio.h>

#include <string.h>


int main()

{

   FILE *file = fopen("./1.txt", "r");

   if(file == NULL)

   {

       printf("open error!\n");

       return 0;

   }

   FILE *fp = fopen("./2.txt", "w");

   char buf[1024] = {0};

   fread(buf, 1024, 1, file);

   fwrite(buf, strlen(buf), 1, fp);

   fclose(file);

   fclose(fp);

   return 0;

}

4、fprintf()与fscanf()结合使用

//以格式化的方式读取,遇到空格或换行就结束,再将读取的文件写入到文件中,优点是可以指定写入的文件格式

示例:

#include <stdio.h>

#include <string.h>


int main()

{

   FILE *file = fopen("./1.txt", "r");

   if(file == NULL)

   {

       printf("open error!\n");

       return 0;

   }

   FILE *fp = fopen("./2.txt", "w");

   char buf[1024] = {0};

   fscanf(file, "%s", buf);

   fprintf(fp, "aaa:%s", buf);

   fclose(file);

   fclose(fp);

   return 0;

}


目录
相关文章
|
19天前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
61 3
|
2月前
|
存储 编译器 C语言
如何在 C 语言中判断文件缓冲区是否需要刷新?
在C语言中,可以通过检查文件流的内部状态或使用`fflush`函数尝试刷新缓冲区来判断文件缓冲区是否需要刷新。通常,当缓冲区满、遇到换行符或显式调用`fflush`时,缓冲区会自动刷新。
|
2月前
|
存储 编译器 C语言
C语言:文件缓冲区刷新方式有几种
C语言中文件缓冲区的刷新方式主要包括三种:自动刷新(如遇到换行符或缓冲区满)、显式调用 fflush() 函数强制刷新、以及关闭文件时自动刷新。这些方法确保数据及时写入文件。
|
2月前
|
C语言
【C语言】探索文件读写函数的全貌(三)
【C语言】探索文件读写函数的全貌
|
2月前
|
存储 C语言
【C语言】探索文件读写函数的全貌(二)
【C语言】探索文件读写函数的全貌
|
2月前
|
C语言
【C语言】探索文件读写函数的全貌(一)
【C语言】探索文件读写函数的全貌
|
2月前
|
存储 文件存储 C语言
【C语言】深入了解文件:简明指南
【C语言】深入了解文件:简明指南
|
3月前
|
Linux C语言
C语言 文件IO (系统调用)
本文介绍了Linux系统调用中的文件I/O操作,包括文件描述符、`open`、`read`、`write`、`lseek`、`close`、`dup`、`dup2`等函数,以及如何获取文件属性信息(`stat`)、用户信息(`getpwuid`)和组信息(`getgrgid`)。此外还介绍了目录操作函数如`opendir`、`readdir`、`rewinddir`和`closedir`,并提供了相关示例代码。系统调用直接与内核交互,没有缓冲机制,效率相对较低,但实时性更高。
|
4月前
|
存储 C语言
【C语言】C语言-学生成绩管理系统(源码+数据文件+课程论文)【独一无二】
【C语言】C语言-学生成绩管理系统(源码+数据文件+课程论文)【独一无二】
63 15
|
4月前
|
存储 C语言
【c语言】职工信息管理系统 包含读取写入txt文件,职工信息的增删改查
【c语言】职工信息管理系统 包含读取写入txt文件,职工信息的增删改查