C 标准输出到文件使用 dup
C stdout to file using dup
我正在开发一个要求用户输入 s、f 或 0 作为用户输入的程序。 S 向系统打印预定义消息,f 将该预定义消息写入用户作为参数提供的文件。 0 终止程序。
我需要让程序只有一个写标准输出的写语句。我必须将 stdout 中打印的预定义消息复制到带有 dup2 的文件中。
现在这两个进程必须通过输入分开(f 写入文件,而 s 写入标准输出)所以我不确定如何在 switch 语句中实现它。
当您输入 f 时,它不应将任何内容打印到标准输出。
这是我的代码:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <sys/wait.h>
#define BUFFER_SIZE 128
#define PERMS 0666
int main(int argc, char *argv[])
{
char outBuffer[BUFFER_SIZE] = "This is a message\n";
int count;
int fd;
char input =0;
int a;
int c;
int k[2];
pipe(k);
if(argc!=2){
printf("Provide an valid file as an argument\n");
exit(1);
}
if((fd = open(argv[1],O_CREAT|O_WRONLY|O_APPEND,PERMS)) == -1)
{
printf("Could not open file\n");
exit(1);
}
printf("0 to terminate, s to write to stdout, f to write to file\n");
do{
scanf(" %c", &input);
switch(input)
{
case 'f':
if((c = fork()) == 0)
{
close(k[0]);
dup2(fd,1);
close(k[1]);
}
else
{
close(k[0]);
close(k[1]);
wait(0);
wait(0);
}
break;
case 's':
write(1,outBuffer,strlen(outBuffer));
break;
default:
printf("Invalid Choice\n");
}
}while(input != '0');
close(fd);
return 0;
}
f 现在只是在按下 s(打印 outBufer 消息)或触发默认开关后将 stdout 定向到文件
我想要的输出:
f
f
s
This is a message
s
This is a message
f
文件包含:
This is a message
This is a message
This is a message
这是我对这个问题的看法;我删除了 fork()
和 pipe()
以在 Windows (gcc -g -std=c11 -Wall -c main.c && gcc main.o -o main.exe
) 上本地编译,因为我认为它们不是必需的。当我 compiled/tested 使用 MSYS2 时,我必须显式刷新标准输出,否则在退出之前不会显示信息性消息。
我重构了 switch
块,以便我们可以用 break
和 continue
控制主循环,我将其重写为 while(1)
.
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#define BUFFER_SIZE 128
#define PERMS 0666
int main(int argc, char *argv[]) {
char outBuffer[BUFFER_SIZE] = "This is a message\n";
int fd, fd_f, fd_s;
char input = 0;
if(argc != 2){
printf("Provide an valid file as an argument\n");
exit(1);
}
if((fd_f = open(argv[1], O_CREAT|O_WRONLY|O_APPEND, PERMS)) == -1){
printf("Could not open file\n");
exit(1);
}
printf("0 to terminate, s to write to stdout, f to write to file\n");
fflush(stdout); // messages are not printed on MSYS2 without explicitly flushing
fd_s = dup(STDOUT_FILENO); // set fd_s to stdout with dup(1)
fd = dup(STDOUT_FILENO);
// if fd is not initialised, calling dup2 will close(0) [i.e. close(stdin)]!
while(1) {
scanf("%c", &input);
fflush(stdin);
if(input == '0') break;
else if(input == 'f') dup2(fd_f, fd); // close(fd) and alias fd_f to fd
else if(input == 's') dup2(fd_s, fd);
else {
printf("Invalid Choice\n");
fflush(stdout);
continue;
}
write(fd, outBuffer, strlen(outBuffer));
}
close(fd_f);
close(fd);
return 0;
}
输出:
标准输出
>main.exe file.txt
0 to terminate, s to write to stdout, f to write to file
f
f
s
This is a message
s
This is a message
f
p
Invalid Choice
0
>
# ./main.exe file.txt
0 to terminate, s to write to stdout, f to write to file
f
f
s
This is a message
f
p
Invalid Choice
0
file.txt
This is a message
This is a message
This is a message
我正在开发一个要求用户输入 s、f 或 0 作为用户输入的程序。 S 向系统打印预定义消息,f 将该预定义消息写入用户作为参数提供的文件。 0 终止程序。
我需要让程序只有一个写标准输出的写语句。我必须将 stdout 中打印的预定义消息复制到带有 dup2 的文件中。
现在这两个进程必须通过输入分开(f 写入文件,而 s 写入标准输出)所以我不确定如何在 switch 语句中实现它。
当您输入 f 时,它不应将任何内容打印到标准输出。
这是我的代码:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <sys/wait.h>
#define BUFFER_SIZE 128
#define PERMS 0666
int main(int argc, char *argv[])
{
char outBuffer[BUFFER_SIZE] = "This is a message\n";
int count;
int fd;
char input =0;
int a;
int c;
int k[2];
pipe(k);
if(argc!=2){
printf("Provide an valid file as an argument\n");
exit(1);
}
if((fd = open(argv[1],O_CREAT|O_WRONLY|O_APPEND,PERMS)) == -1)
{
printf("Could not open file\n");
exit(1);
}
printf("0 to terminate, s to write to stdout, f to write to file\n");
do{
scanf(" %c", &input);
switch(input)
{
case 'f':
if((c = fork()) == 0)
{
close(k[0]);
dup2(fd,1);
close(k[1]);
}
else
{
close(k[0]);
close(k[1]);
wait(0);
wait(0);
}
break;
case 's':
write(1,outBuffer,strlen(outBuffer));
break;
default:
printf("Invalid Choice\n");
}
}while(input != '0');
close(fd);
return 0;
}
f 现在只是在按下 s(打印 outBufer 消息)或触发默认开关后将 stdout 定向到文件
我想要的输出:
f
f
s
This is a message
s
This is a message
f
文件包含:
This is a message
This is a message
This is a message
这是我对这个问题的看法;我删除了 fork()
和 pipe()
以在 Windows (gcc -g -std=c11 -Wall -c main.c && gcc main.o -o main.exe
) 上本地编译,因为我认为它们不是必需的。当我 compiled/tested 使用 MSYS2 时,我必须显式刷新标准输出,否则在退出之前不会显示信息性消息。
我重构了 switch
块,以便我们可以用 break
和 continue
控制主循环,我将其重写为 while(1)
.
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#define BUFFER_SIZE 128
#define PERMS 0666
int main(int argc, char *argv[]) {
char outBuffer[BUFFER_SIZE] = "This is a message\n";
int fd, fd_f, fd_s;
char input = 0;
if(argc != 2){
printf("Provide an valid file as an argument\n");
exit(1);
}
if((fd_f = open(argv[1], O_CREAT|O_WRONLY|O_APPEND, PERMS)) == -1){
printf("Could not open file\n");
exit(1);
}
printf("0 to terminate, s to write to stdout, f to write to file\n");
fflush(stdout); // messages are not printed on MSYS2 without explicitly flushing
fd_s = dup(STDOUT_FILENO); // set fd_s to stdout with dup(1)
fd = dup(STDOUT_FILENO);
// if fd is not initialised, calling dup2 will close(0) [i.e. close(stdin)]!
while(1) {
scanf("%c", &input);
fflush(stdin);
if(input == '0') break;
else if(input == 'f') dup2(fd_f, fd); // close(fd) and alias fd_f to fd
else if(input == 's') dup2(fd_s, fd);
else {
printf("Invalid Choice\n");
fflush(stdout);
continue;
}
write(fd, outBuffer, strlen(outBuffer));
}
close(fd_f);
close(fd);
return 0;
}
输出:
标准输出
>main.exe file.txt
0 to terminate, s to write to stdout, f to write to file
f
f
s
This is a message
s
This is a message
f
p
Invalid Choice
0
>
# ./main.exe file.txt
0 to terminate, s to write to stdout, f to write to file
f
f
s
This is a message
f
p
Invalid Choice
0
file.txt
This is a message
This is a message
This is a message