首页 > 解决方案 > 在 C 中,如何将 -o 合并为命令行参数,以将输出写入另一个文件而不是标准输出?

问题描述

我目前有一个程序 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;
    }

非常感谢任何帮助或解决方案。谢谢!

标签: ccommand-lineoutputcommand-line-arguments

解决方案


1) 输出重定向

如果你在 linux 上,你可以使用输出重定向,比如

myprogram testfile > outputfile

2)getopt()

如果您在 POSIX 系统上,您可能想调查一下getopt()(您可能在使用 POSIX 系统时getline())。在其他平台上也可能有等效的方法。有关Windows 中 getopt 功能的讨论,请参阅此内容。

有了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()如果您拥有它,那将是更好的选择。

Ifo是您拥有的唯一选项,并且它总是被指定为-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]以 a 开头"-o"。如果是这样,我们看看这是否就是其中的全部内容argv[i]。如果这就是其中的全部内容,我们argv[i+1]将查找文件名。
如果"-o"in之后有某些argv[i]内容,我们将其余部分argv[i]视为输出文件的名称。

所以两者

myprogram testfile -o outputfile

myprogram testfile -ooutputfile

将文件名提取为"outputfile".


在字符数组中获取如此获得的文件名之后,例如filename,您可以使用freopen()as

freopen(filename, "w", stdout);

现在stdout成为与我们的输出文件关联的流。从现在开始,任何写入操作都stdout将意味着写入该文件。

stdout首先关闭,然后打开filename并将此文件与文件流相关联stdout

或者freopen(),您可以通过使用fopen()as打开文件来创建另一个流,而不是使用

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

然后用foutas in写

fprintf(fout, "%s", "output......");

推荐阅读