重定向标准输入和标准输出?

时间:2018-11-07 18:22:52

标签: c io

因此,我试图将I / O重定向为从文件读取命令,然后当用户运行输出命令时,它将打印已编译的命令以输出文件。

例如在终端上:

./run 2 < test.txt // This would take file using dup and take the input

然后,当您要输出编译时:

./run 1 > output.txt // and it would put into an output file

到目前为止,我知道如何输出到文件,但是我的问题是输入。如何使用dup2()函数从文件中获取命令?我试图对此进行研究,但没有运气。

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

char inputForOutput[100];

void functionOutput(int argc, char **argv){

    int ofd; //Init of file desc.

    ofd = open(argv[1], O_CREAT|O_TRUNC|O_WRONLY);

    dup2(ofd, 1);//Duplicates to stdout

    system("ls");//Copies commnd given to output_file
}

//Function is called when argument number is == 1
void functionInput(int argc, char **argv){
    FILE *ifd;
        printf("\n %s \n ", argv[2]);
    ifd = fopen(argv[2] , "r");
    if (ifd == NULL){
        perror("No file found");
        exit(1);
    }
    fscanf(ifd,"%s",inputForOutput);
    printf("\n**%s**\n",inputForOutput);
}

int main(int argc, char **argv)
{
    int output;
    int input;
    output = strcmp("1", argv[1]);
    input = strcmp("2" ,argv[1]);
    if (output == 0 ) { //Fail safe for number of arguments
        functionOutput(argc, argv);
    }
    else if ( input == 0){
        functionInput(argc, argv);
    }
    else{
        fprintf(stderr, "How to use: %s function output_file\n", argv[0]); // FAIL SAFE IF INPUT DOES NOT MATCH BOTH FUNCTIONS
    }
    return 0;
}

3 个答案:

答案 0 :(得分:0)

使用functionOutput(),您可以很好地尝试将系统命令的输出捕获到文件中。实际上, that 是第一个参数为1时调用的函数,因此您可能要更新注释。另外,您正在创建一个文件,其名称存储在argv[1]中,我们已经知道它的名称为1,因此它可能未达到您的期望,并且可能需要:

ofd = open(argv[2], O_CREAT|O_TRUNC|O_WRONLY);

使用functionInput(),您正在从文件中读取第一个非空白条目。如果您告诉它读取使用functionOutput()函数输出的文件,则可能是ls列出的第一个文件的名称(其中一部分)。

我发现不清楚您想做什么,不是那样。如果您想找出运行该命令以生成输出的内容,则该信息无法从文件本身获得,因为您未在其中写入信息。如果这是您想要的,则可能需要考虑将命令写为文件的第一行,然后是输出。然后,当您阅读它时,可以假定第一行是命令运行,然后是该命令的输出。

答案 1 :(得分:0)

要重定向输入和输出,请使用此格式

myprogram > out.txt < in.txt //read from in.txt, write to out.txt
myprogram < in.txt > out.txt //read from in.txt, write to out.txt
myprogram < in.txt //redirect stdin only
myprogram > out.txt //redirect stdout only
myprogram //no redirection
...

这适用于任何程序。示例:

int main(void)
{
    char buf[1000];
    if(fgets(buf, sizeof(buf), stdin))
        printf("write: %s\n", buf);
    return 0;
}

要在程序中重定向stdin / stdout,请使用标准方法

freopen("output.txt", "w", stdout);
printf("Testing...");
fclose(stdout);

freopen("input.txt", "r", stdin);
char buf[100];
fgets(buf, sizeof(buf), stdin);
fclose(stdin);

或者,设置FILE *fin = stdin; FILE* fout = stdout;来重定向相​​反的方式。

接下来,要使用argv元素编写程序,请始终首先测试argc。下面的代码显示了一个示例。

#include <stdio.h>
#include <string.h>

int redirect(int argc, char **argv, int *index)
{
    //no more redirection!
    if(*index >= argc)
        return 1;

    //not enough parameters
    if(*index + 1 >= argc)
    {
        printf("wrong usage\n");
        return 0;
    }

    if(strcmp(argv[*index], "<") == 0)
    {
        *index++; //next parameter is to redirect input
        if(!freopen(argv[*index], "r", stdin))
            printf("error, redirect input failed");
    }
    else if(strcmp(argv[*index], ">") == 0)
    {
        *index++; //next parameter is to redirect output
        if(!freopen(argv[*index], "w", stdout))
            printf("error, redirect output failed");
    }
    else
    {
        printf("wrong usage\n");
        return 0;
    }

    return 1;
}

int main(int argc, char **argv)
{
    int index = 1;
    if(!redirect(argc, argv, &index))
        return 1;

    if(!redirect(argc, argv, &index))
        return 1;

    //read
    char buf[1000];
    if(fgets(buf, sizeof(buf), stdin))
    {
        //write
        printf("write: %s\n", buf);
    }

    fclose(stdin);
    fclose(stdout);

    return 0;
}

答案 2 :(得分:0)

如果我理解您的问题,并且希望以两种不同的模式运行程序,(1)如果要在stdin上进行输入,则希望进行输入; (2)如果没有输入等待,您想输出,那么select/pselectpoll是您要寻找的东西。

例如,select使您可以检查是否已准备好在文件描述符(或一组描述符)上读取输入,并且它将返回输入等待的描述符数目(或-1并将errno设置为错误)。您可以简单地使用STDIN_FILENO(a / k / a fd 0)来检查stdin上是否有输入,例如

#include <stdio.h>
#include <unistd.h>         /* for STDIN_FILENO */
#include <sys/select.h>     /* for pselect   */

int input (int filedes)
{
    fd_set set;

    /* declare/initialize zero timeout */
    struct timespec timeout = { .tv_sec = 0 };

    /* Initialize the file descriptor set. */
    FD_ZERO (&set);
    FD_SET (filedes, &set);

    /* check whether input is ready on filedes */
    return pselect (filedes + 1, &set, NULL, NULL, &timeout, NULL);
}

int main (void)
{
    if (input (STDIN_FILENO))
        puts ("doing input routine");
    else
        puts ("doing output routine");

    return 0;
}
手册页中的

注意::“ select()使用struct timeval(以秒和微秒为单位)的超时,而pselect()使用{ {1}}(以秒和纳秒为单位。”)

使用/输出示例

struct timespec