使用getopt在C中解析参数

时间:2016-07-02 20:44:36

标签: c parsing getopt

我正在尝试解析传递给我的程序的参数,以便在函数中使用它们。 参数的格式为:

0
timed out
1
timed out
2
timed out

我想保存emp ­­-p one.txt two.txt three.bin ­-­o file.emp 中-p之后的参数以及char **arg_pack-o之后的参数。

以下是我的代码的一部分:

char **arg_output

它给了我一个分段错误。那是为什么?

3 个答案:

答案 0 :(得分:1)

根据Linux手册页

  

默认情况下,getopt()会在扫描时置换argv的内容,因此   最终所有的非选通都在最后。

所以当你尝试在while循环中索引到argv时,你正在索引到一个argv,它可能不像你开始使用的argv。

答案 1 :(得分:1)

关于此代码:

extern char *optarg;
extern int optind, opterr, optopt;

char **arg_pack;
char **arg_output;

int arg_pack_count = 0;
int arg_output_count = 0;

while ((res = getopt(argc, argv, OPTION_STRING)) != -1 )
{
    if (res == (int) OP_ARG_PACK)
    {   
        int index = optind - 1;
        arg_pack_count++;
        while(index < argc)
        {   
            *arg_pack = malloc(strlen(argv[index])+1 );
            strcpy(arg_pack[index], argv[index]);
            index++;

            if ( (index<argc) && ((argv[index])[0] == '-') )
            {         
                optind = index - 1;
                break;
            }
        }
            emp_pack(arg_pack,arg_output);
}

seg错误的原因是使用了指向任何已分配内存的指针(带偏移索引)。

malloc()的调用会不断覆盖变量中的指针(如果有):char **arg_pack;

getopt()只有在找到&#39;之后才能访问下一个参数。选项并且不会处理无效选项,也不会处理选项后的(预期)多个值。

分配所需内存的一个更容易(虽然稍微浪费)的方法是:

char * argpack = NULL;
if (NULL == (argpack = malloc( argc * sizeof(char *) ) ) )
{ // then malloc failed
    perror( "malloc for -p array of pointers failed" );
    exit( EXIT_FAILURE );
}

// implied else, malloc successful

if( NULL == (argoutput = malloc( argc * sizeof( char *) ) ) )
{ // then malloc failed
    perror( "malloc for -o array of pointers failed" );
    free( argpack );
    exit( EXIT_FAILURE );
}

// implied else, malloc successful

while( .... )
{
    .... // use `strdup()` to set the pointers
}

然而,发布的代码的逻辑并没有出错。

建议:

size_t argpackIndex = 0;
size_t argoutputIndex = 0;

char lastSeenOption = '\0';

for( int x=1; x<argc; x++ ) // 1 to skip over executable file name
{
    if( '-' == argv[x][0] )
    {
        lastSeenOption = tolower(argv[x][1]);
    }

    else
    {
         switch( lastSeenOption )
         {
             case 'p':
                argpack[ argpackIndex ] = strdup( argv[x] );
                argpackIndex++;
                break;

             case 'o':
                argoutput[argoutputIndex ] = strdup( argv[x] );
                argoutputIndex++;
                break;

             default:
                fprinf( stderr, "ignoring invalid option: <%c> for parameter value: <%s>\n", 
                        lastSeenOption,
                        argv[x] );
                break;
        } // end switch
    } // end if
} // end for

答案 2 :(得分:1)

<div class="modal fade" id="contact" role="dialog" >
<div class="modal-dialog">
    <div class="modal-content">
        <form class="form-horizontal" role="form" name="contact-form">
            <div class="modal-header">
                <h4>test</h4>
            </div>
            <div class="modal-body"><p>This is body</p></div>
            <div class="modal-footer">
                <button type="submit" id="submit" class="btn btn-primary btn-lg" onclick="alert('something');">Send</button>
            </div>
        </form>
    </div>
</div>

arg_pack指向NULL。就在这里:

char **arg_pack; 

我认为这会取消引用空指针并尝试分配给它。

尝试类似

的内容
*arg_pack = malloc(strlen(argv[index])+1 );

某处,如果arg_pack_count到达arg_pack_max,realloc()并为arg_pack获取更多空间