Skip to content
Davide Fiorito edited this page Aug 6, 2022 · 7 revisions

How to use pargvc

After including the pargvc.h header in your code, it's time to see how pargvc allows you to quickly interact with argv.

argv and argc

To use pargvc, it's necessary to add two arguments in main(): int argc and char** argv.

#include <stdio.h>
#include <pargvc.h>

int main(int argc, char** argv)
{
    //code
}

argv collects every word typed in the command launched to start your CLI program. The first (0th in the argv array index) item is the "call" itself: in the command ./myapp -f check --whatever, argv[0] is "./myapp".

argc is the number of items inside argv.

First steps

To initialize pargvc, we need to call the pargvc_init function; name checks out.

void pargvc_init(char** argv, int argc);

  • char** argv, int argc: pass argv and argc as values for this argument, so that pargvc can copy them for later access.

Declaring arguments

To declare a mandatory argument, use add_mandatory_argument.

add_mandatory_argument(const char* flag, , const char* help)

  • const char* flag: this is the name assigned to the mandatory argument. An example may be "FILE_TO_OPEN", for a program which file content.

  • const char* help: a brief explanation of what the argument is. Not mandatory, but surely helpful when the --help flag will be called.

To declare an optional argument, use add_optional_argument.

What are optional arguments? Optional arguments may be flags (like --connect-using-wpa2) or additional info given to the app (like ./openfile myfile --open-mode read+write)

int add_optional_argument(const char* flag, const char* extended, int value_level, const char* help)

  • const char* flag: it's recommended to give a value starting with a minus sign and then a single char, like -m.
  • const char* extended: it's recommended to give a value starting with two minus sign and then a full word, like --connect-mode.
  • int value_level: this value is used to determine how pargvc will behave during value assignment.

According to the header, value_level values are 0 and 1.

  • 0 or VAL_REQ: value required

    If the value is missing, an error will come up. This is the best value_level for a mandatory argument.

  • 1 or VAL_OPT: value optional

    If a value is given, it will be stored; if not, the value assigned to that argument will be "TRUE".

  • 2 or VAL_NOT: value not accepted

    Value won't be stored; Instead of using this value level, it's better to call add_switch

  • const char* help: same as add_mandatory_argument.

Switches

pargvc supports switches, which are special optional arguments: they do not accept values, but instead act like switches: if they are called inside the command, a "TRUE" value will be assigned. Like a switch on/off state.

Accessing argument values

After declaring all the arguments our application needs, it's time to call parse_argv(). This function will iterate through argv and assigns a value to each argument that needs it.

Accessing the value of an argument is really simple: just call get_arg_value(arg).

<arg> is a const char*, and has to be the flag you assigned to the value you need. If you're getting the value of an optional argument, you can also use its extended flag.

It's also possible to quickly check if an optional flag has been called, using check_flag(arg). It will return 1 if arg is in argv, 0 if not. Note that, if you need to use the optional flag just as a switch which doesn't need a value (so value_level is set to 1), it's more efficient to call check_flag than comparing the flag value to "TRUE".

Let's see a quick example:

//main.c
/*
This program takes a file, reads it
and then can delete or copy it;
also, can print the number of characters in it

Please note that, except for pargv functions, this is pseudocode: compiling it
without making the appropriate corrections will result in unexpected behavior
*/
#include <stdio.h>
#include <string.h>
#include <pargvc.h>
#include <some_file_io_lib.h>

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

    add_mandatory_argument("FILE", "File to open");
    add_optional_argument("-c", "--char-number", VAL_OPT, "Print the number of chars in the file. Accepts number of chars as value");
    add_optional_argument("-d", "--delete", VAL_REQ, "YES to delete after reading, NO to keep the file");
    add_switch("--c", "--confirm-delete", "Ask for user input to delete file);

    parse_argv();

    myfile = open_file(get_arg_value("FILE"), "read-mode");
    print_file_content(myfile);

    if(strcmp(get_arg_value("--char-number"), "TRUE")==0)
    // equivalent to
    // if(check_flag("--char-number")==1)
    {
        print_number_of_chars();
    }

    if(check_flag("--delete")==1)
    {
        if(strcmp(get_arg_value("--delete"), "YES")==0)
        {
            delete_file(myfile);
            if(check_flag("--user-confirm")==1)
            {
                if(ask_user_confirm()=="proceed")
                {
                    printf("File %s deleted!\n", get_arg_value("FILE"));
                }
            }
            else
            {
                printf("File %s deleted!\n", get_arg_value("FILE"));
            }
        }
        else if(strcmp(get_arg_value("--delete"), "NO")==0)
        {
            printf("File %s won't be deleted!\n", get_arg_value("FILE"));
        }
        else
        {
            printf("\'%s\' is not a valid value for --delete!\n", get_arg_value("--delete"));
        }

    } else { printf("--delete not in argv; keeping the file\n"); }

    pargvc_end();
    // Call this function to deallocate all the memory used by pargvc

    return 0;
}

Note that we called pargvc_end at the end of the application: this function will deallocate all the memory taken by pargvc, making it available for new use. However, it's highly recommended to not call this function until you need to interact with arguments.

To compile this code, we have to tell gcc we're using the non-standard library pargvc: this is done by adding -lpargvc in the compile command.

gcc main.c -o file_reader -lpargvc

Clone this wiki locally