您的位置:首页 > 编程语言 > C语言/C++

C语言常见文件操作

2016-04-01 22:51 295 查看
在C语言中主要通过标准的I/O函数来对文本文件进行操作。常见的文本操作函数包括

fopen()(打开) fclose()(关闭) fgetc()(读取字符) fputs()(写入字符) fprintf()(写入) fscanf()(读取)

1.打开文件

函数原型:

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


其中:

path :文件完整路径(如果没有指定路径,则默认为当前工作目录)

mode :为指定的打开模式

如果打开成功,fopen会返回一个结构指针地址,否则返回一个NULL。

FILE *fp;
fp = fopen("c:\\temp\\test.txt", "r")


使用fopen()函数打开的文件会先将文件复制到缓冲区。注意:所下达的读取或写入动作,都是针对缓冲区进行存取而不是磁盘,只有当使用fclose()函数关闭文件时,缓冲区中的数据才会写入磁盘。

1.1打开模式:

“r”:只能从文件中读数据,该文件必须先存在,否则打开失败

“w”:只能向文件写数据,若指定的文件不存在则创建它,如果存在则先删除它再重建一个新文件

“a”:向文件增加新数据(不删除原有数据),若文件不存在则会建立该文件

“r+”:可读/写数据,该文件必须先存在,否则打开失败

“w+”:可读/写数据,用该模式打开新建一个文件,先向该文件写数据,然后可读取该文件中的数据

“a+”:可读/写数据,原来的文件不被删去,位置指针移到文件末尾

打开二进制文件的模式与打开文本文件的含义是一样的,不同的是模式名称里面多一个字母’b’,以表示以二进制形式打开文件。

2.关闭文件:

函数原型:

int fclose( FILE *fp );


返回值:如果流成功关闭,fclose 返回 0,否则返回EOF(-1)。(如果流为NULL,而且程序可以继续执行,fclose设定error number给EINVAL,并返回EOF。)

注:在执行完文件的操作后,要进行“关闭文件”操作。虽然程序在结束前会自动关闭所有的打开文件,但文件打开过多会导致系统运行缓慢,这时就要自行手动关闭不再使用的文件,来提高系统整体的执行效率。

FILE *fp;
fp = fopen("c:\\temp\\test.txt", "r");

if(fp == NULL)
printf("fail to open the file! \n");
else
{
printf("The file is open! \n");
fclose(fp);
}


3.字符存取函数

函数原型为:

int fputc (char c, File *fp)


int fgetc(FILE *stream);


字符读取函数fgetc()可从文件数据流中一次读取一个字符,然后读取光标移动到下一个字符,并逐步将文件的内容读出。

如果字符读取成功,则返回所读取的字符,否则返回EOF(end of file)。EOF是表示数据结尾的常量,真值为-1。另外,要判断文件是否读取完毕,可利用feof()进行检查。未完返回0,已完返回非零值。

feof()函数原型为:

int feof(FILE *stream);


#include <stdio.h>

main()
{
FILE *fp; fp = fopen("c:\\temp\\test.txt", "r");
if(fp != NULL)
{
while(!feof(fp))
printf("%c", fgetc(fp));
}
else
printf("fail to open! \n");
fclose(fp);

return 0;
}


若要将字符逐一写入文件,用fputc()函数。

示例为:

#include <stdio.h>
#include <conio.h>

main()
{
char filename[20], ch;
FILE *fp;
printf("Enter a filename: ");
scanf("%s", filename);
printf("Enter some characters to output to file: ");
if((fp = fopen(filename, "w")) == NULL)
printf("fail to open! \n");
else
{
while((ch = getche()) != '\015')
fputc(ch, fp);
}
fclose(fp);

return 0;
}


4.字符串存取函数

函数原型为:

int  fputs(const char *, FILE *);


char *  fgets(char *, int, FILE *);


fgets函数的作用是从指定文件读入一个字符串,如:fgets(str, n, fp);

参数n为要求得到的字符个数,但只从fp指向的文件输入n-1个字符,然后在最后加一个’\0’字符,因此得到的字符串共有n个字符,把它们放在字符数组str中。如果在读完n-1个字符之前遇到换行符或EOF,读入结束。

fputs函数的作用是向指定文件输出一个字符串,如:fputs(“Hey”, fp);

把字符串”Hey”输出到fp指向的文件。fputs函数的第一个参数可以是字符串常量、字符数组名或字符型指针。若输出成功,则返回0,否则返回EOF。

2.5 格式化存取函数

函数原型为:

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


int  fscanf(FILE *, const char *, ...);


它们与printf和scanf函数相仿,都是格式化读写函数。不同的是:fprintf和fscanf函数的读写对象不是终端(标准输入输出),而是磁盘文件。printf函数是将内容输出到终端(屏幕),因此,fprintf就是将内容输出到磁盘文件了。

#include <stdio.h>

void main()
{
FILE *fp;

int num = 10;
char name[10] = "Leeming";
char gender = 'M';

if((fp = fopen("info.txt", "w+")) == NULL)
printf("can't open the file! \n");
else
fprintf(fp, "%d, %s, %c", num, name, gender); //将数据格式化输出到文件info.txt中

fscanf(fp, "%d, %s, %c", &num, name, &gender); //从文件info.txt中格式化读取数据
printf("%d, %s, %c \n", num, name, gender); //格式化输出到屏幕

fclose(fp);
}


5. 指针重返函数

函数原型为:

void  rewind(FILE *);


rewind函数的作用是使位置指针重返回文件的开头,属于文件的定位。

6.二进制文件操作

6.1 数据块存取函数

函数原型:

size_t  fread(void *, size_t, size_t, FILE *);


size_t  fwrite(const void *, size_t, size_t, FILE *);


当要求一次存取一组数据(如,一个数组、一个结构体变量的值),fread和fwrite函数可以解决该类问题。它们的调用形式一般为:

fread(buffer, size, count, fp);

fwrite(buffer, size, count, fp);

buffer:对于fread来说,指的是读入数据的存放地址;对于fwrite来说,是要输出数据的地址。

size:读写数据时,每笔数据的大小

count:读写数据的笔数

fp:文件指针

#include <stdio.h>
#define SIZE 3

typedef enum { MM, GG } Gender;

typedef struct
{
char name[10];
int  age;
Gender gender;
} Person;

void write2file(Person emp[SIZE])
{
FILE *fp;
if((fp = fopen("emp.txt", "wb")) == NULL)
{
printf("cannot open file! \n");
return;
}

for(int i=0; i<SIZE; i++)
if(fwrite(&emp[i], sizeof(Person), 1, fp) != 1)
printf("file write error! \n");
fclose(fp);
}

void read_from_file(FILE *fp)
{
Person emp_out[SIZE];

if((fp = fopen("emp.txt", "rb")) == NULL)
{
printf("cannot open file! \n");
return;
}

printf("\n%d employee's information read: \n", SIZE);

for(int i=0; i<SIZE; i++)
{
if(fread(&emp_out[i], sizeof(Person), 1, fp) != 1)
if(feof(fp))
{
fclose(fp);
return;
}
printf("%-5s %4d %5d \n", emp_out[i].name, emp_out[i].age, emp_out[i].gender);
}
fclose(fp);
}

void main()
{
FILE *fp = NULL;
Person employee[SIZE];

printf("Enter %d employee's information: \n", SIZE);
for(int i=0; i<SIZE; i++)
scanf("%s %d %d", employee[i].name, &employee[i].age, &employee[i].gender);

write2file(employee);

read_from_file(fp);
}


7. 随机存取函数fseek()

函数原型:

int  fseek(FILE *, long, int);


对流式文件可以进行顺序读写,也可以进行随机读写。关键在于控制文件的位置指针,如果位置指针是按字节位置顺序移动的,就是顺序读写。如果能将位置指针按需要移动到任意位置,就可以实现随机读写。所谓随机读写,是指读完上一个字符(字节)后,并不一定要读写其后续的字符(字节),而可以读写文件中任意位置上所需要的字符(字节)。该函数的调用形式为:

fseek(fp, offset, start);


start:起始点。用0、1、2代替。0代表文件开始,名字为SEEK_SET,1代表当前位置,名字为SEEK_CUR,2代表文件末尾,名字为SEEK_END。

fseek()函数一般用于二进制文件,因为文本文件要发生字符转换,计算位置时往往会发生混乱。

调用实例如:

fseek(fp, i*sizeof(Person), 0);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: