从C中的文件解析参数的最简单方法是什么?

时间:2016-10-03 21:48:40

标签: c file parameters arguments parameter-passing

考虑文件ArgumentFile.txt

int a=100;
int b[3] = { 5, 2, 5 };
double c = 0.0014;

主要代码code.c

int main(int argc, char *argv[])
{
   if (argc > 1) FILE *f = fopen(argv[1], "r");
   ParseFile(f); // Set the parameters based on file
   DoStuff(a,b,c); // Run the process based on the parsed arguments
}

用户可以通过执行

传递参数
./CodeExecutable ArgumentFile.txt

是否有解析文件参数的标准解决方案?它将等同于getopt从命令行解析参数?

3 个答案:

答案 0 :(得分:3)

您不需要等效getopt(),您可以使用getopt()getopt()函数不专门处理命令行参数;它将处理命令行参数的 style 中任何指向字符串的指针数组。

#define MAX_ARGS 256
#define MAX_FILE_LEN 4096

int main(int argc, char *argv[])
{
   if( argc > 1 )
   {
      FILE *f = fopen(argv[1], "r");
      if( f != 0 )
      {
         char fargs[MAX_FILE_LEN] = "" ;
         fread( fargs, 1, MAX_FILE_LEN, f ) ;

         // Build fargv from file content
         char* fargv[MAX_ARGS] ;
         int fargc = 0 ;

         fargv[fargc] = strtok( fargs, " \n\r" ) ;

         while( fargc < MAX_ARGS && fargv[fargc] != 0 )
         {
            fargc++ ;
            fargv[fargc] = strtok( 0, "\n\r" ) ;
         }

         // Process fargv using getopt()
         while( (char c = getopt( fargc, fargv, "a:b:c:")) != -1 )
         {
            switch( c )
            {
               ...
            }
         }
      }
   }

   ...

   return 0 ;
}

使用实际文件长度动态分配fargs可能更好,但上述内容仅供参考。

您的输入文件可能如下所示:

-a 100
-b 5,2,5
-c 0.0014

getopt()循环必须根据需要处理参数 - 例如使用sscanf()

        switch( c )
        {
           case 'a' : sscanf( optarg, "%i", a ) ; break ;
           case 'b' : sscanf( optarg, "%i,%i,%i", b[0], b[1], b[2] ) ; break ;
           case 'c' : sscanf( optarg, "%f", c ) ; break ; 
        }

        DoStuff( a, b, c ) ;

答案 1 :(得分:2)

我使用getopt()。这是一个允许更多灵活性的示例。这个例子演示了如何处理可选的optarg和多个optarg。

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

void usage(void)
{
    printf("usage: \n"
           "This example demonstrates how to add flexibility to the traditional linux getopt()\n"
           "This help text is printed if the program is executed without arguments\n"
           "or with an invalid argument configuration.\n"
           "to view the help file run without arguments or with -h\n"
           "Oterwise the program accepts two options: -d, -u\n"
           "-d: can come with 0 or one option argument\n"
           "-u: can come with one or more option arguments\n"
           "try this to see the output:\n"
           "./test -d aaa -u ccc 4 \"quoted multi token string\" -d -u\n");
}

int main(int argc, char **argv)
{
    char data[101];
    int opt;

    memset(data, 0, 101);
    while ((opt = getopt(argc, argv, "hd:u:t:")) != -1) {
        switch (opt) {
        case 'h':
            usage();
            return 0;
        case 'd': // can accept 0 or 1 parameters
            if (optarg[0] == '-') { //not an optarg of ours...
                optind--;
                printf("option: -d. no tokens (another option follows)\n");
                break;
            }
            strncpy(data, optarg, 100);
            printf("option: -d. tokens: %s\n", data);
            break;
        case 'u': //can accept one or more parameters ...
            strncpy(data, optarg, 100);
            printf("option: -u. tokens: %s", data);
            //do we have more arguments for 'u'?
            while( optind <= argc && argv[optind][0] != '-') {
                strncpy(data, argv[optind], 100);
                printf(", %s", data);
                optind++;
            }
            printf(".\n");
            break;
        case ':': //this happens if we got an option which expects an arg without any optarg.
            if(optopt == 'd') {//lets allow a '-d' without its optarg
                printf("option: -d. no tokens\n");
                break;
            }
            //otherwise fall through to the default handler
        default: //covers ':' '?' for missing value,  '-h' for help, etc.
            printf("on error you get: opt=%c. optopt=%c opterr=%d\n", opt, optopt, opterr);
            return 0;
        }
    }
    return 0;
}

答案 2 :(得分:1)

使用纯C代码无法做到这一点。您必须编写特定于平台的汇编语言代码来处理它。

您最好的选择是使用C预处理器。

int main(int argc, char *argv[])
{
#include "myfile.txt"
   // Do Stuff 
}

话虽如此,我不知道你会得到什么,而不是直接将myfile.txt的内容放在main()中。