本次实验是输出重定向,实验目的是实现 printf 输出字符写到test.txt文件中。
实验环境是阿里云ubuntu16.04系统。编译器是gcc5.4版本。
思路是先关闭文件描述符1 使用close函数和dup函数
文件描述符前三个是固定的,0号文件描述符是输入文件描述符,1号文件描述符是输出文件描述符,2号是错误文件描述符。所以先关闭1号文件描述符。dup()函数的作用是返回一个新的文件描述符,从0 开始找个空闲的文件描述符。由于刚才把文件描述符1关闭了。所以1号文件描述符为空闲,就fd文件描述符就指向了1号文件描述符。所以 printf()输出的字符指向了fd文件描述符。fd文件描述符是打开了test.txt文件。所以重定向到了test.txt文件中。这样就使得 printf() 函数输出的字符打印在了 test.txt 中。从而实现文件重定向。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <dirent.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
int main()
{
int fd;
fd = open("test.txt",O_WRONLY);
if( fd == -1)
{
ERR_EXIT("open error");
}
close(1);
dup(fd);
printf("11111111");
return 0;
}
注意:在文件夹下要有 test.txt 文件夹,要不然会没有发现文件。或者open函数的时候创建一个也是可以的。
第二种重定向得方法使用dup2函数
dup2函数的功能是强制使用文件描述符,不管文件描述符1是否关闭都可以使用文件描述符1.类似于先关闭文件描述符1在dup一下
dup2(fd,1); 只需要这一个就可以了。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <dirent.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
int main()
{
int fd;
fd = open("test.txt",O_WRONLY);
if( fd == -1)
{
ERR_EXIT("open error");
}
// close(1);
// dup(fd);
dup2(fd,1);
printf("12345657890");
return 0;
}
还有一种就是使用fcntl函数实现文件重定向。
fcntl函数和dup函数类似,不过功能要强大的多,fcntl(fd,F_DUPFD,0) 这个函数有三个参数,第一个是文件描述符 fd 。第二个参数的意思是复制文件描述符的意思。第三个参数的意思是从0开始搜索可以用的文件描述符。所以先删除文件描述符1.
当然fcntl 函数功能很强大,可以根据第二个参数完成不同的任务。(本次实验不讨论)
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <dirent.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0)
int main()
{
int fd;
fd = open("test.txt",O_WRONLY);
if( fd == -1)
{
ERR_EXIT("open error");
}
//close(1);
//dup(fd);
//dup2(fd,1);
close(1);
if(fcntl(fd,F_DUPFD,0) < 0)
{
ERR_EXIT("dup fd error");
}
printf("hello\n");
return 0;
}