Egjupss Egjupss - 3 months ago 10
C Question

Program in C to read arguments

I started to learn C and I want to create a program which will take 2 obligatory arguments and 1 optional. `
This question may sound elementary but I have difficulty in understanding it.
So basically what I want to do is to call the program like this:

myfile -n name -a age -g grade


So when I call it this will be valid:
myfile john 22 20

Name
and
age
are
obligatory
. So
name
is a string,
age
is a number between 0 and 100.
And
grade
is
optional
and can be a number. If it isn't defined then the value of it will be 0.

I tried to do it like this:

#include<stdio.h>
#include<string.h>
int getopt(int argc, char * const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;

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

FILE *fp;
char *filename = "student.txt";

char name;
int age, grade;
if( (fp = fopen(filename, "w")) == NULL) {
// show error
printf("Error.");
}
if(argc!=2)
{
printf("Error.");
return;
}
int ich = 0;
while ((ich = getopt (argc, argv, "abc")) != -1) {
switch (ich) {
case 'a':
name = argv[1];
break;
case 'b':
age = argv[2];
if not (age >= 0 && age<100) {
printf("Error.");
}
break;
case 'c':
grade = argv[3];
if (grade == NULL) {
grade = 0;
}
break;
default:
break;
}
}
fprintf(fp,"%s, %d, %d",name, age, grade);
fclose(fp);
}


I want to use pointer
optarg
to have access to the arguments.
I get this error
warning: assignment makes integer from pointer without a cast [-Wint-conversion]

I really need help. Please, can someone help me. I really need help. :(

Here is my tutorialspoint fiddle

Answer

After discussion etc, I created this code based on the code from the question:

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

static char *arg0 = 0;
static void usage(void)
{
    fprintf(stderr, "Usage: %s -n name -a age [-g grade]\n", arg0);
    exit(EXIT_FAILURE);
}

int main(int argc, char **argv)
{
    FILE *fp;
    char *filename = "student.txt";
    char *name = 0;
    int age = 0;
    int grade = 22;

    arg0 = argv[0];

    int opt;
    while ((opt = getopt(argc, argv, "n:a:g:")) != -1)
    {
        switch (opt)
        {
        case 'n':
            name = optarg;
            break;
        case 'a':
            age = atoi(optarg);
            if (age <= 0 || age >= 100)
            {
                fprintf(stderr, "Age '%s' out of range 1..99\n", optarg);
                usage();
            }
            break;
        case 'g':
            grade = atoi(optarg);
            break;
        default:
            break;
        }
    }

    if (name == 0)
    {
        fprintf(stderr, "You did not specify a name\n");
        usage();
    }
    if (age == 0)
    {
        fprintf(stderr, "You did not specify an age\n");
        usage();
    }
    if (optind != argc)
    {
        fprintf(stderr, "Extra arguments provided (starting with '%s')\n", argv[optind]);
        usage();
    }

    // check if file exists
    if ((fp = fopen(filename, "w")) != NULL)
    {
        printf("%s, %d, %d\n", name, age, grade);
        fprintf(fp, "%s, %d, %d\n", name, age, grade);
        fclose(fp);
    }
    else
    {
        fprintf(stderr, "Failed to open file '%s' for writing\n", filename);
        return 1;
    }
    return 0;
}

Example runs

Program name: go59

$ go59
You did not specify a name
Usage: go59 -n name -a age [-g grade]
$ go59 -n Rita
You did not specify an age
Usage: go59 -n name -a age [-g grade]
$ go59 -n Rita -a 23
Rita, 23, 22
$ go59 -n Andromeda -a 23 -g 97
Andromeda, 23, 97
$ go59 -n Andromeda -a 23 -g 97 apoplexy
Extra arguments provided (starting with 'apoplexy')
Usage: go59 -n name -a age [-g grade]
$ go59 -n Andromeda -a 23 -g 97 --
Andromeda, 23, 97
$ go59 -n Andromeda -a -1 -g 97 --
Age '-1' out of range 1..99
Usage: go59 -n name -a age [-g grade]
$ go59 -n Andromeda -a 0 -g 97 --
Age '0' out of range 1..99
Usage: go59 -n name -a age [-g grade]
$

Note that the code doesn't zap the student.txt file until it knows that the arguments it was given are valid enough.