2013-11-02 183 views
1

我得到来自用户的命令行参数。Optarg和命令行参数

我那么做开关的情况下的命令,例如:

case 'f': 
     *file_name = optarg; 
     break; 

我不确定我是否需要对malloc的指针,因为我不完全理解OPTARG。

这是FILE_NAME的声明方式:

char **file_name; 

我应该为字符串长度+ 1做

int length = strlen(optarg); // This gives a warning about types when compiling. 

然后的malloc?

malloc应该如何处理这类问题?请记住,用户正在将文件名输入到** argv中。

编辑:这是我如何调用这个功能,仍然是分段错误。

int main(int argc, char **argv) 
{ 
    char **file_name; 
    parser(argc, argvm file_name); 
} 

void parser(int argc, char **argv, char **file_name) 
{ 
    // Switch cases. 
} 

回答

4

'optarg'只是指向argv []中元素的指针。因此,不分配内存并复制'optarg'指向的值是安全的。

假设你的PROGRAMM被称为具有下列参数:

myapp -a "hello" -b "world" 

和你的代码是:

#include <stdio.h> 
#include <getopt.h> 

void parse_options(int argc, char* argv[], char ** first_arg, char ** second_arg) 
{ 
    const char* opt_string = "a:b:"; 
    int opt = -1; 
    opt = getopt(argc, argv, opt_string); 
    while (opt != -1) { 
    switch(opt) { 
     case 'a': 
     *first_arg = optarg; /* points to argv[2]="hello" */ 
     break; 
     case 'b': 
     *second_arg = optarg; /* points to argv[4]="world" */ 
     break; 
     default: 
     break; 
     } 
    opt = getopt(argc, argv, opt_string); 
    } 
} 

int main(int argc, char* argv[]) 
{ 
    char* first = 0; 
    char* second = 0; 
    parse_options(argc, argv, &first, &second); 
    printf("first=%s, second=%s\n", first, second); 
    return 0; 
} 

我的输出:

freebsd% gcc -Wall main.c 
freebsd% ./a.out -a hello -b world 
first=hello, second=world 
+0

我一直在这条线越来越分段故障FILE_NAME = OPTARG;如果我在一个函数中做这件事,这有什么关系吗? (我会发布上面的代码) –

+0

哎呀,忽略了。 char *文件名应该工作。 – dnk

+0

我的逻辑是我需要传递一个指向file_name指针的指针,以便接收main中的文件名。 –

1

你说你有:

char **file_name; 
... 
switch (opt) 
{ 
case 'f': 
    *file_name = optarg; 
    break; 
... 
} 

代码崩溃,因为您尚未分配空间或初始化变量file_name

你需要做什么取决于你想要发生什么。最通常情况下,你会改变的file_name的定义:

char *file_name = 0; 
... 
switch (opt) 
{ 
case 'f': 
    file_name = optarg; 
    break; 
... 
} 

这允许您检测,循环/开关之后,是否提供了一个文件名,你可以提供一个默认或报告错误,如果不。在这种情况下,您可以检测是否先前提供了文件名,如果是,则提供对象。

另一种方案是,您希望允许在命令行上多次使用-f。然后你需要建立一个指针数组,保持它们的数量。你可能会这样写:

char **file_name = 0; 
size_t num_files = 0; 
size_t max_files = 0; 
... 
switch (opt) 
{ 
case 'f': 
    if (num_files == max_files) 
    { 
     size_t new_files = (max_files + 2) * 2; 
     void *new_space = realloc(file_name, new_files * sizeof(*file_name)); 
     if (new_space == 0) 
      ...report out of memory error... 
     file_name = new_space; 
     max_files = new_files; 
    } 
    file_name[num_files++] = optarg; 
    break; 
... 
} 

这将使用如果传入的指针为NULL,它模拟malloc()realloc()奇财产。或者,您可以在循环外执行初始malloc()分配,并在循环内执行(相同)realloc()。大小的计算首先分配4个条目,然后分配12个,然后是28个等。如果您担心过度分配,可以在循环完成后调整大小以适应大小,然后再次使用realloc(),但这可能不会影响很多。

循环之后,你有你也许会处理文件列表:

for (size_t i = 0; i < num_files; i++) 
    process_file(file_name[i]);