我正在从用户那里获得命令行参数。
然后,我为命令切换大小写,例如:
case 'f':
*file_name = optarg;
break;
我不确定我是否需要对指针进行 malloc,因为我不完全理解 optarg。
file_name是这样声明的:
char **file_name;
我应该做吗
int length = strlen(optarg); // This gives a warning about types when compiling.
那么字符串长度 + 1 的 malloc
?对于这种问题,应该如何做malloc?请记住,用户正在 **argv 中键入file_name。
编辑:这就是我调用此函数的方式,但仍然出现分段错误。
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.
}
'optarg' 只是指向 argv[] 中元素的指针。因此,不分配内存并复制"optarg"指向的值是安全的。
假设使用以下参数调用您的程序:
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=%sn", first, second);
return 0;
}
我的输出:
freebsd% gcc -Wall main.c
freebsd% ./a.out -a hello -b world
first=hello, second=world
你说你有:
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;
...
}
这使用 realloc()
的奇数属性,如果传入的指针为 NULL,则模拟malloc()
。 或者,您可以在循环外执行初始malloc()
分配,并在循环内执行(相同的)realloc()
。 对大小的计算第一次分配 4 个条目,然后是 12 个,然后是 28 个,依此类推。 如果您担心过度分配,可以在循环完成后再次使用 realloc()
将大小调整为正确的大小,但这可能不会对事情产生太大影响。
循环之后,您将得到一个可以处理的文件列表:
for (size_t i = 0; i < num_files; i++)
process_file(file_name[i]);