В C как включить -o в качестве параметра командной строки, чтобы записать вывод в другой файл, а не в стандартный вывод? - PullRequest
0 голосов
/ 01 мая 2018

В настоящее время у меня есть программа myprogram.c, которую можно вызывать с аргументами командной строки, такими как myprogram testfile. Это будет читать текст из testfile, если он существует, а функция spaces() изменит текст и выведет его на стандартный вывод. Однако я хочу иметь возможность вызывать программу наподобие myprogram testfile -o outputfile, чтобы вместо печати в стандартный вывод вывод записывался в outputfile. Как бы я поступил так?

Далее следует общая структура моей основной.

  int main (int argc, char *argv[])
    {
        char *a;
        char *prev_line[999];
        size_t len = 0;
        size_t read;

      /* if there is more than one argument */
      if (argc > 1)
        {
          a = malloc (MAX_NAME_SZ * sizeof (char));
          int i = 1;
          FILE *fp;
          while (i < argc)
        {
          fp = fopen (argv[i], "r");
            if (fp == NULL)
              {
                /*Error statement in case file doesn't exist */
              }
            else
             {
               char* line = NULL;
             while ((read = getline(&line, &len, fp)) != -1) {
              /*code to create char array a */        
              }
          }   
            free(line);
            fclose (fp);
            }
          i++;   
        }
        }
      else /* if no command line arguments */
        {
          /* get array a from stdin*/
          spaces (a);
           return 0;
        }
          spaces (a);
          return 0;
    }

Любая помощь или решение с благодарностью. Спасибо!

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

1) Перенаправление вывода

Если вы работаете в Linux, вы можете просто использовать перенаправление вывода, например

myprogram testfile > outputfile

2) getopt ()

Возможно, вы захотите заглянуть в getopt(), если находитесь в системе POSIX (возможно, вы используете getline()). Там могут быть эквивалентные способы и на других платформах. См. this для обсуждения функциональности getopt в Windows.

С getopt() это легко. Что-то вроде

#include<unistd.h>
#include<ctype.h>
int main(int argc, char **argv)
{
    int c;
    while( (c=getopt(argc, argv, "o:"))!=-1 )
    {
        switch(c)
        {
        case 'o':

            printf("\nFile name is: %s" , optarg);
            break;
        case '?':
            if(isprint(optopt))
            {
                printf("\nUnknown option %c", optopt);
            }
            else
            {
                printf("\nUnknown option: %x", optopt);
            }

        }
    }
    while(optind < argc)
    {
        printf("\nRemaining args: %s", argv[optind++]);
    }
}

Прочтите справочную страницу и эту страницу.


3) Ручной способ

Вы должны проанализировать аргументы командной строки. Этот способ может вызвать множество ошибок и ошибок. Как отмечается в комментариях, getopt() будет лучшим выбором, если он у вас есть.

Если o - единственный вариант, который у вас есть, и он всегда будет указан как -o, вы можете сделать что-то вроде

int main(int argc, char **argv)
{
    for(int i=1; i<argc; ++i)
    {
        if(argv[i][0]=='-' && argv[i][1]=='o')
        {
            if(argv[i][2]=='\0')
            {
                printf("\nstandalone o found.");
                if(i+1 < argc)
                {
                    printf("\nOutput file: %s", argv[i+1]);
                }
                else
                {
                    printf("\nOutput file name not given.");    
                    return 1;
                }
            }
            else
            {
                printf("\nOutput file name (closer): %s", argv[i]+2);
            }
        }
    }           


    . . . . . . . . . . 
    . . . . . . . . . . 

}

Сначала мы проверяем, начинается ли argv[i] с "-o". Если это произойдет, мы увидим, что это все, что есть в этом argv[i]. Если это все, мы смотрим на argv[i+1], чтобы найти имя файла.
Если после "-o" в argv[i] что-то есть, мы рассматриваем оставшуюся часть argv[i] в качестве имени выходного файла.

Так что оба

myprogram testfile -o outputfile

и

myprogram testfile -ooutputfile

извлечет имя файла как "outputfile".


После получения имени файла, полученного таким образом в массиве символов, скажем, filename, вы можете использовать freopen(), как в

freopen(filename, "w", stdout);

Теперь stdout становится потоком, связанным с нашим выходным файлом. Отныне любые операции записи в stdout будут означать запись в этот файл.

Поток stdout сначала закрывается, а затем открывается filename и связывает этот файл с потоком файлов stdout.

Или вместо использования freopen(), вы можете просто создать другой поток, открыв файл с fopen(), как в

FILE *fout = fopen(filename, "w");

, а затем писать fout, как в

fprintf(fout, "%s", "output......");
0 голосов
/ 01 мая 2018

Разобрать argv [i] для -o, затем, когда вы найдете его, используйте argv [i + 1] для создания или открытия ФАЙЛА, в который вы хотите записать, откройте его с помощью FILE * out_file = fopen (argv [i +1], "w") использование fprintf (out_file, "output format \ n"); написать ему.

В основном все ваши printfs станут fprintf, и вы передаете указатель файла на каждый его вызов, хотя все спецификаторы формата одинаковы. Вы все еще можете использовать printf, но он не пойдет в файл, вы также можете использовать fprintf (stderr, ""); для регистрации ошибок, если ваша программа продолжает расти, и вам нужна консольная регистрация.

перед выходом из вашей программы обязательно закройте файл, fclose (out_file).

...