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+ | 以读/写方式打开一个文本文件,允许读或在文本末追加数据。 |
例如:
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语言的长时间来,对使用过的数据类型、库函数的归纳总结,在已知的东西中找到自己未知的过程。