Bootstrap

Linux系统编程4--标准c库对文件的操作(fopen、fread、fwrite、fseek、fclose、fputc、fgetc、feof)

Linux系统编程4–标准c库对文件的操作(fopen、fread、fwrite、fseek、fclose、fputc、fgetc、feof)

1、总结openfopen的区别

  • man fopenlinux低下查找某API的用法

<总结open与fopen的区别 - NickyYe - 博客园 (cnblogs.com)>

  • 区别:
    • 来源:open是UNIX系统调用函数(包括LINUX等),返回的是文件描述符(File Descriptor),它是文件在文件描述符表里的索引;fopen是ANSIC标准中的C语言库函数。返回的是一个指向文件结构的指针。
    • 移植性:fopen是C标准函数,因此拥有良好的移植性;而open是UNIX系统调用,移植性有限。
    • 缓冲:open无缓冲,fopen有缓冲。前者与read, write等配合使用, 后者与fread,fwrite等配合使用。

2、fopen、fwrite、fseek、fread、fclose的使用

  • 包含头文件#include <stdio.h>

2.1 fopen

//FILE *fopen(const char *path, const char *node);
//两个参数都是指针,=地址=字符串 ---> 用双引号
fp = fopen("./tp.txt","w+");
  • 返回值:为一个指针

2.2 fwrite

//size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
//ptr      buf	     这是指向带有最小尺寸 size*nmemb 字节的内存块的指针。
//size     sizeof()  这是要读取的每个元素的大小,以字节为单位。
//nmemb    strlen()  这是元素的个数,每个元素的大小为 size 字节。
//*stream  fp	     这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流。
fwrite(str, sizeof(char),strlen(str),fp);
//fwrite(str, sizeof(char)*strlen(str),1,fp);//第二种写法
  • 返回值:第三个参数
    • nmemb个数 strlen(str)

2.3 fseek

//注意光标问题
//int fseek(FILE *stream, long offset, int whence);
fseek(fp,0,SEEK_SET);

2.4 fread

//size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
fread(readBuf,sizeof(char), strlen(str),fp);
//fread(readBuf, sizeof(char)*strlen(str),1,fp);//第二种写法
  • 返回值:第三个参数
    • nmemb 读出来多少个数

2.5 fclose(fp) 关闭 fp

2.6 程序演示

//demo.c
#include <stdio.h>
#include <string.h>

int main()
{	
	FILE *fp;
	char *str = "tp222 nb666";
	char readBuf[128] = {0};

//	FILE *fopen(const char *path, const char *node);
	//两个参数都是指针,=地址=字符串 ---> 用双引号
	fp = fopen("./tp.txt","w+");

//	size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
	//ptr      buf	     这是指向带有最小尺寸 size*nmemb 字节的内存块的指针。
	//size     sizeof()  这是要读取的每个元素的大小,以字节为单位。
	//nmemb    strlen()  这是元素的个数,每个元素的大小为 size 字节。
	//*stream  fp	     这是指向 FILE 对象的指针,该 FILE 对象指定了一个输入流。
	fwrite(str, sizeof(char),strlen(str),fp);
	//fwrite(str, sizeof(char)*strlen(str),1,fp);//第二种写法


	//注意光标问题
//	int fseek(FILE *stream, long offset, int whence);
	fseek(fp,0,SEEK_SET);


//	size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
	fread(readBuf,sizeof(char), strlen(str),fp);
	//fread(readBuf, sizeof(char)*strlen(str),1,fp);//第二种写法
	
	printf("read data:%s\n",readBuf);
    fclose(fp);
	return 0;
}

3、写入结构体到文件


  • 程序演示
demo2.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

struct Test
{
	int a;
	char c;
};

int main()
{
	FILE *fp;
	struct Test data = {100,'a'};
	struct Test data2;

	fp = fopen("./file1","w+");

	int n_write = fwrite(&data,sizeof(struct Test),1,fp);
	
	fseek(fp,0,SEEK_SET);
	int n_read = fread(&data2,sizeof(struct Test),1,fp);

	printf("read %d,%c \n",data2.a,data2.c);
	fclose(fp);

	return 0;
}
  • 与前面一篇文章差不多,稍微改一下参数就ok;

4、fgetc/fgets、fputc/fputs、feof的使用

在学习新 API 的时候,

第一:我们可以在网站上面搜索;

第二:我们可以在 Liunx 系统里面,利用命令 man + API来查看该 API 的详情;

4.1 fputc、fputs

int fputc(int c, FILE *stream);
int fputs(const char *s, FILE *stream);
  • 添加头文件#include<stdio.h>

  • 将 int 类型的 数值或者字符串,放入 FILE 对象的指针,该 FILE 对象标识了要被写入字符的流

  • 程序演示

//demo3.c
#include <stdio.h>
#include <string.h> //利用到了strlen()函数

int main()
{
	FILE *fp;
	int i;
	char *str = "tp222 nb666";
	int len = strlen(str);

	fp = fopen("./test.txt","w+");
	for(i=0; i<len; i++)
	{
		fputc(*str,fp);//将字符串一个个字符放入fp
		str++;
	}
	fclose(fp);
	return 0;
}

4.2 feof()

int feof(FILE *stream);
  • 是否到达文件的尾巴
    • 未到达文件尾巴:零
    • 到达文件尾巴:非零

4.3 fgetc

int fgetc(FILE,*stream);
  • 从该文件中一个个读取字符

  • 返回值:读取到的字符

  • 程序演示

//demo4.c
#include <stdio.h>
#include <string.h> //利用到了strlen()函数

int main()
{
	FILE *fp;
	int i;
	char c;	
	fp = fopen("./test.txt","r");

	while(!feof(fp))//如果到达文件尾部,返回 非零;
	{
		c = fgetc(fp);
		printf("%c ",c);
	}

	fclose(fp);
	return 0;
}

欢迎大家一起交流讨论!

;