No idea how to use popt library

Kuan Source

All:

Thanks for help.

I am new to C option parsing, for now, what I want is to use popt library to parsing the each argument and prnit them out.

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <popt.h>

    using namespace std;

    int main(int argc, const char* argv[]){

        char* dt1;
        char* dt2;

        struct poptOption {
               const char * longName; /* may be NULL */
               char shortName;        /* may be ’\0’ */
               int argInfo;
               void * arg;            /* depends on argInfo */
               int val;               /* 0 means don’t return, just update flag */
               char * descrip;        /* description for autohelp -- may be NULL */
               char * argDescrip;     /* argument description for autohelp */
            };
        struct poptOption optionsTable[]={
            {"start",'s',POPT_ARG_STRING,dt1,'s',"The date format should like YYYY-MM-DD.",0},
            {"end",'e',POPT_ARG_STRING,dt2,'e',"The date format should like YYYY-MM-DD.",0},
            //~ POPT_AUTOHELP
            //~ {NULL,0,0,NULL,0}
            };

        poptContext optCon;
        optCon = poptGetContext (0, argc, argv, optionsTable, 0);

            const char* portname = poptGetArg(optCon);
        cout<<portname<<endl;
        return 0;
}

When I compile it, I got error llike:

test.cpp: In function ‘int main(int, const char**)’
test.cpp:27: warning: deprecated conversion from string constant to ‘char*’
test.cpp:27: warning: deprecated conversion from string constant to ‘char*’
test.cpp:30: error: cannot convert ‘main(int, const char**)::poptOption*’ to ‘const poptOption*’ for argument ‘4’ to ‘poptContext_s* poptGetContext(const char*, int, const char**, const poptOption*, unsigned int)’

c++clinux

Answers

answered 5 years ago Craig McQueen #1

I don't think you should be defining the struct poptOption in your program. That struct should be defined for you in the popt include file. Try removing that struct definition.

Note, I think you also need to uncomment this line:

    //~ {NULL,0,0,NULL,0}

answered 5 years ago Edwin Buck #2

The reason that this warning is being reported is a feature of the C language, but the mistake in the code is due to how you are attempting to use popt.

The types (char*) and (const char*) in C are different types. One is not really the other, and while C allows assignment from one type to another without blowing up, any decent C compiler will give you a warning. You can hide the warnings with a type cast, but it's generally a bad idea.

A C-style string is of the type (const char*), and you are assigning it to the field descrip in poptOption which is defined as a (char*). This raises a compiler warning because now, someone who reaches into that memory by following the reference from the optionsTable array could attempt to change the contents of the string. That's an odd thing to allow, considering the string is defined as a constant. That's why you get the warning.

The mistake in your code is that you are using popt incorrectly, with your own definition of the poptOption struct. If you look within the file that you include (popt.h) on line 55 you will see the poptOption struct, as it is defined by the popt authors. It is:

struct poptOption {
    /*@[email protected]*/ /*@[email protected]*/ const char * longName;    /* may be NULL */
     char shortName;         /* may be '\0' */
    int argInfo;
     /*@[email protected]*/ /*@[email protected]*/ void * arg;          /* depends on argInfo */
    int val;                /* 0 means don't return, just update flag */
     /*@[email protected]*/ /*@[email protected]*/ const char * descrip;       /* description for autohelp -- may be NULL */
    /*@[email protected]*/ /*@[email protected]*/ const char * argDescrip;    /* argument description for autohelp */
};

or removing comments

struct poptOption {
    const char * longName;
    char shortName;
    int argInfo;
    void * arg;        
    int val;              
    const char * descrip;   
    const char * argDescrip; 
};

and you clearly see that even the authors expected a (const char *), and not the (char *) you defined.

comments powered by Disqus