изменение программы на языке c, поэтому требуется дополнительный аргумент командной строки * infile * - PullRequest
2 голосов
/ 29 октября 2009

Теперь у меня есть вопрос для всех ... Я смотрел на это в течение нескольких дней, пытаясь что-то переделать и поиграть, но даже при этом я получаю массу ошибок ...

Я пытаюсь взять приведенную ниже программу и изменить ее так, чтобы она принимала необязательный аргумент командной строки infile . Если задано infile , скопируйте infile в стандартный вывод, в противном случае скопируйте стандартный ввод в стандартный вывод, как раньше.

Хитрость в том, что решение должно использовать исходный цикл копирования (строки 9-11) для обоих случаев. Можно только вставить код, а не изменять какой-либо существующий код. Любая помощь будет отличной. Спасибо.

/* $begin cpfile */
include "csapp.h"
int main(int argc, char **argv)
{
    int n;
    rio_t rio;
    char buf[MAXLINE];

    Rio_readinitb(&rio, STDIN_FILENO);                  //line 9
    while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) //line 10
        Rio_writen(STDOUT_FILENO, buf, n);              //line 11
        /* $end cpfile */
        exit(0);
        /* $begin cpfile */
    }
/* $end cpfile */

Ответы [ 3 ]

5 голосов
/ 29 октября 2009
Программы

C получают аргументы командной строки через два аргумента для main(), традиционно называемые argc и argv (для количества аргументов и вектора аргумента соответственно).

Аргументы ничего не "именуют", они просто строки.

Решение для вас может выглядеть так:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    int fileno;
    /* ... your definitions should remain here, too */

    if(argc > 1)
    {
       /* Assume first argument is filename, and open it. */
       fileno = open(argv[1], O_RDONLY);
       if(fileno < 0)
       {
         printf("Unable to open file, aborting\n");
         return 1;
       }
    }
    else
      fileno = STDIN_FILENO;

  /* ... your code goes here ... */
}

Тогда вам, конечно, нужно изменить вызов на Rio_readinitb(), чтобы использовать переменную fileno для дескриптора файла.

Если вы буквально не можете изменить эту строку по какой-то причине ... Я думаю, вы можете использовать препроцессор для того, чтобы символ получил новое имя переменной:

#undef  STDIN_FILENO
#define STDIN_FILENO fileno

Это, конечно, не совсем красиво, но должно работать.

Убедитесь, что вы поставили эти макросы препроцессора после строки fileno = STDIN_FILENO;.

1 голос
/ 29 октября 2009

Вы можете вставить dup2 перед строками 9 - 11, и кажется, что вам не нужно менять код в строках 9 - 11. Это пример.

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>


int main(int argc, char *argv[])
{

    int file_handle;
    int dup2_res;
    if (argc == 2) {
        file_handle = open(argv[1], O_RDONLY);
        dup2_res = dup2 (file_handle, STDIN_FILENO);
    }

    char buffer[100];
    ssize_t read_bytes = 1;
    while (read_bytes)
    {
        read_bytes = read(STDIN_FILENO, &buffer, sizeof(buffer) );
        buffer[read_bytes] = 0;
        printf("%s", buffer);
    }
    close(file_handle);

    return 0;
}
1 голос
/ 29 октября 2009

Если STDIN_FILENO нельзя переназначить, это звучит как задание для freopen():

freopen(argv[1], "r", stdin);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...