Remi.b Remi.b - 1 month ago 6
C Question

What is the easiest way to parse arguments from a file in C?

Consider a file

ArgumentFile.txt


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


And the main code
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
}


A user could then pass arguments by doing

./CodeExecutable ArgumentFile.txt


Is there a standard solution to parse arguments from file? It would be an equivalent of
getopt
which parse arguments from command line?

Answer

You do not need an equivalent to getopt() you can use exactly getopt(). The getopt() function does not specifically process command line arguments; it will process any array of pointers to strings in the style of command line arguments.

#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 ;
}

It is probably better to dynamically allocate fargs using teh actual file length, but the above is illustrative only.

Your input file might then look like:

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

The getopt() loop will then have to process the arguments as necessary - using sscanf() for example.

        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 ) ;
Comments