2013-11-02 181 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]);