C语言细看从头|<stdio.h>的两大open函数:fopen()与popen()

C语言细看从头|stdio.h的fopen与popen

一、fopen()

FILE *fopen(const char *filename, const char *mode);
@filename:文件路径
@mode:打开模式 如下表格
return:返回FILE *类型的文件描述符号

int fclose(FILE *fp);
@fp:需要关闭的文件的文件描述符
return:0成功,错误返回EOF(-1)
mode说明
r以只读方式打开文件,该文件必须存在。
r+以读/写方式打开文件,该文件必须存在。
w打开只写文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。
w+打开可读/写文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。
a以附加的方式打开只写文件。若文件不存在,则会创建该文件;如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(EOF 符保留)。
a+以附加方式打开可读/写的文件。若文件不存在,则会创建该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(EOF符不保留)。
rb+以读/写方式打开一个二进制文件,只允许读/写数据。
rt+以读/写方式打开一个文本文件,允许读和写。
wb以只写方式打开或新建一个二进制文件,只允许写数据。
wb+以读/写方式打开或新建一个二进制文件,允许读和写。
wt+以读/写方式打开或新建一个文本文件,允许读和写。
ab+以读/写方式打开一个二进制文件,允许读或在文件末追加数据。
at+以读/写方式打开一个文本文件,允许读或在文本末追加数据。

节选fopen百度百科

例如:

FILE *fp1=NULL;
	fp1=fopen(FILE1,"r");
	if(fp1==NULL)printf("r错误!%d\n",errno);
	else {
		printf("r成功打开 %s\n",FILE1 );
		fclose(fp1);
	}

若打开错误,会将错误码放入errno中,例如在例子中若FILE1不存在,则会输出:

r错误!2

在errno.h中定义:

#define ENOENT 2 /* No such file or directory */

意思为没有该文件或该目录。

1、fwrite()

size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
@buffer:指向数据块的指针
@size:每个数据的大小,单位为Byte(例如:sizeof(int)就是4)
@count:数据个数
@stream:文件指针
return :写入的字节数量
#include <stdio.h>
#include <string.h>   	//strlen memcpy
#include <errno.h>		//errno
#include <stdlib.h>   	//malloc
#define FILE4 	"./filefopen/file4"
void my_fopen(void)
{
	FILE *fp=NULL;
	fp=fopen(FILE4,"w+");
	if(fp==NULL)printf("w+错误!%d\n",errno);
	else {
		char *wrtbuf=(char *)malloc(1024*sizeof(char));
		char *str="一键三连";
		memcpy(wrtbuf,str,strlen(str));  //注意不可使用wrbuf="一键三连",申请内存的指针不可作为左值
		fwrite(wrtbuf,sizeof(char),strlen(wrtbuf),fp);
		fclose(fp);
		free(wrtbuf);
	}
}

查看是否写入

# cat filefopen/file4
一键三连

2、fread()

size_t fread(void *buffer, size_t size, size_t count, FILE *stream);
@buffer:指向数据块的指针
@size:每个数据的大小,单位为Byte(例如:sizeof(int)就是4)
@count:数据个数
@stream:文件指针
retrun:读取的字节数

注意:在写完后记得fclose后再fopen

	FILE *fpread=NULL;
	fpread=fopen(FILE4,"r");
	if(fpread==NULL)printf("w+错误!%d\n",errno);
	else {
		char *rettbuf=(char *)malloc(1024*sizeof(char));
		//一次读1个byte,最多读1024次
		int ret=fread(rettbuf,1,1024,fpread);
		printf("read:%dbyte %s\n",ret,rettbuf );
		//清空数据内存
		memset(rettbuf,0,strlen(rettbuf));
		//将文件指针指向文件开头偏移0的位置
		fseek(fpread,0,SEEK_SET);
		//换一次读1024个byte,最多读1次
		ret=fread(rettbuf,1024,1,fpread);//第二种读法
		printf("read:%dbyte %s\n",ret,rettbuf );
		fclose(fpread);
		free(rettbuf);
	}

输出:

read:12byte 一键三连
read:0byte 一键三连

第一次一次读1个byte,读了12个byte。
第二次一次读1024个byte,因为只有12个byte所以还没读够,返回0。

二、popen()

#include <stdio.h>
FILE *popen(const char *command, const char *type);
@command :指令
@type:只能是“r”或“w”
return:返回与fopen一样的文件描述符

int pclose(FILE *stream);
@stream:文件路径
return:成功返回0,错误返回EOF

popen()函数的作用其实就是在程序中使用shell命令,调用fork()产生一个子进程,执行一个shell以运行命令来开启一个进程。
获取命令返回值使用

函数char *fgets(char *s, int size, FILE *stream);
@s:读取数据存放的缓冲区
@size:读取数据大小
@stream:文件流也就是文件描述符
return:当n<=0返回NULL,成功返回首地址

例如使用popen获取当前进程号

void my_popen(void)
{
	FILE* fp=(FILE*)popen("ps -ef|grep -w template|grep -v grep","r");
	char *readbuf=(char*)malloc(sizeof(char)*128);
	fgets(readbuf,128,fp);
	printf("%s\n",readbuf );
	pclose(fp);
	free(readbuf);
	return;
}

输出:

//	UID	PID	   PPID  C STIME  TTY 	 TIME	   CMD
	xxx 11682  9004  0 14:45 pts/3  00:00:00 ./template

细看从头,是我对于接触C语言的长时间来,对使用过的数据类型、库函数的归纳总结,在已知的东西中找到自己未知的过程。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ySh_ppp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值