本文中的代码是国嵌实验手册上的,并非原创,自己添上注释。
linux中文件编程可以使用两种方式:linux系统调用和C语言库函数。前者依赖于linux系统,后者和操作系统是独立的,在任何操作系统下,使用C语言库函数操作文件的方法都是相同的。
实验2-1-1 文件编程—文件创建
一、源代码及注释
/*需求:创建一个可读可写的文件*/
#include
#include
#include
#include
#include
void create_file(char *filename)
{
/*判断创建的文件是否成功*/
if(creat(filename,0666)<0)/*若创建成功内核向进程返回文件描述符(非负数)*/
{
printf("create file %s failure!\n",filename);
exit(EXIT_FAILURE);
}
else
printf("create file %s success!\n",filename);
}
/*函数功能:主函数*/
int main(int argc,char *argv[]) /*argc是命令行参数的数目,argv是指向参数的各指针所构成的数组(指针数组)*/
{
/*判断用户是否输入文件名*/
if(argc<2) /*命令行参数只有本程序文件名*/
{
printf("you haven't input filename,please try again!\n");
exit(EXIT_FAILURE);/*正常结束进程函数,终止状态为EXIT_FAILURE=1,在终端echo $?打印终止码*/
}
create_file(argv[1]);
exit(EXIT_SUCCESS);
}
二、详点说明
1、文件创建函数creat的参数说明——“0666”,不难理解6代表的是可读可写,在运行该程序后,创建出的文件的权限是这样的“-rw-r--r--",即真正可读可写的只有该用户自己。
2、exit()和return()函数的区别:
exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束。
return() 是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如果不是,那就是退回上一层调用。
实验2-2-2 文件编程——文件拷贝
一、源代码
/*使用库函数实现文件copy功能*/
#include
#include
#include
#define BUFFER_SIZE 1024
int main(int argc,char *argv[])
{
FILE *from_fd; //定义FILE结构体,存放打开源文件返回值
FILE *to_fd;
long file_len=0;
char buffer[BUFFER_SIZE];
/*判断入参是否为三,即本文件名,源文件名和目的文件名*/
if(argc!=3)
{
printf("Usage:%s fromfile tofile\n",argv[0]);
exit(EXIT_FALURE);
}
/*打开源文件*/
if((from_fd=fopen(argv[1],"rb"))==NULL)
{
printf("Open %s Error!\n",argv[1]);
exit(EXIT_FALURE);
}
/*创建目的文件*/
if((to_fd=fopen(argv[2],"wb"))==NULL)
{
printf("Open %s Error!\n",argv[2]);
exit(EXIT_FALURE);
}
/*测试源文件大小*/
fseek(from_fd,0L,SEEK_END); //将源文件指针指到文件尾
file_len=ftell(from_fd); //取得文件指针位置,返回位置值,即文件大小
fseek(from_fd,0L,SEEK_SET); //将源文件指针指回到文件头
printf("from file size is %d\n",file_len);
/*进行文件拷贝*/
while(!feof(from_fd)) //检查文件指针是否到了文件尾
{
fread(buffer,BUFFER_SIZE,1,from_fd); //从源文件读取BUFFER_SIZE*1,存入buffer中
/*判断能否一次写完*/
if(BUFFER_SIZE>=file_len)
{
fwrite(buffer,BUFFER_SIZE,1,to_fd);
}
else
{
fwrite(buffer,file_len,1,to_fd);
file_len=file_len-BUFFER_SIZE;
}
memset(buffer,0,BUFFER_SIZE); //将buffer中长度BUFFER_SIZE的数据写零
}
fclose(from_fd);
fclose(to_fd);
exit(EXIT_SUCCESS);
}
二、详点说明
1、关于FILE结构体:FILE定义的数据类型是一种结构体类型,FILE结构体与具体的编译器和系统有关。Linux系统下,在/usr/include/stdio.h中定义为typedef struct_IO_FILE FILE,即一种结构体类型。
2、源程序中本来使用bzero()函数将buffer清零,故了解下这两个函数的用法和区别:
bzero原型:void bzero(void *s,int n);
用法:#include
功能:置字符串s的前n个字节为零且包括'\0'。
说明:bzero无返回值,并且使用strings.h头文件,strings.h曾经是POSIX标准的一部分,但是在POSIX.1-2001标准里面,这些函数被标记为了遗留函数而不推荐使用。在POSIX.1-2008标准里已经没有这些函数了。推荐使用memset替代bzero。
实验2-2-2 vfork创建子进程
一、源代码
/*需求:编写程序使用vfork创建一子进程,分别在父进程和子进程中打印进程ID,并观察父子进程的运行顺序*/
#include
#include
#include
#include
#include
int main(void)
{
pid_t child;
/*创建子进程*/
if((child=vfork())<0)
{
printf("Fork Error:%s\n",strerror(errno));
exit(1);
}
else
if(child==0) //子进程
{
sleep(1); //子进程睡眠一秒
printf("I am the child:%d\n",getpid());
exit(0);
}
else //父进程
{
printf("I am the father:%d\n",getpid());
return 0;
}
}
二、详点说明
fork与vfork的区别:
1、fork:子进程拷贝父进程的数据段,即子进程创建后与父进程相互独立运行
vfork:子进程共享父进程的数据段。
2、fork:父、子进程的运行顺序不确定
vfork:父进程必须等待子进程运行结束才能运行。
实验2-2-3 exec函数族
一、源代码
/*需求:使用系统调用execl函数创建一个文件*/
#include
#include
#include
int main(int agrc,char *argv[])
{
/*判断入参有没有传入文件名*/
if(agrc<2)
{
perror("You haven't input the filename,please try again!\n");
exit(1);
}
/*调用execl函数,用可执行程序file_creat替换本进程*/
if(execl("./file_creat","file_creat",argv[1],NULL)<0)
perror("execl error!\n"); /*perror将你输入的信息和errno对应的错误信息一起打印出来*/
}
二、详点说明
perror函数、strerror函数、erron的关系和区别:
1、errno是错误码,在errno.h头文件中;
2、strerror函数,通过参数errno将错误码对应的错误信息返回;
3、perror函数,将你输入的信息和errno对应的错误信息一起返回。
实验2-2-4 进程等待
一、源代码
/*需求:编写程序创建一子进程,父进程需要等待子进程运行完后才能执行*/
#include
#include
#include
#include
#include
#include
int main(void)
{
pid_t child;
/*创建子进程*/
if((child=fork())<0)
{
printf("Fork Error:%s\n",strerror(errno));
exit(1);
}
else
if(child==0) //子进程
{
printf("the child process is run\n");
sleep(1); //子进程睡眠一秒钟,但并没有去执行父进程
printf("I am the child:%d\n",getpid());
exit(0);
}
else //父进程
{
wait(NULL); //阻塞父进程,直到子进程退出
printf("the father process is run\n");
printf("I am the father:%d\n",getpid());
return 0;
}
}
二、详点说明
wait()参数设置为NULL,将不返回子进程结束状态值。
Linux 常用C函数 点击打开链接
Linux头文件汇总 点击打开链接