解析具有不确定数量的参数的命令行

时间:2014-11-19 00:53:27

标签: c core argv

我担心如何在参数数量不确定时解析参数。

例如,我们可以考虑任何核心转储应用程序。

store_dump中注册应用程序(例如:/proc/sys/kernel/core_pattern)时,只要发生本机崩溃,就会调用store_dump应用程序。我们可以在注册期间提供各种选项,以便我们希望收到哪些论据。

我的选项是 - %p %e %s(pid, executable file name(thread name), signal number)

所以我打算将参数读作

argv[1] -> pid
argv[2] -> thread name
argv[3] -> signal number

除非我在帖子名称中有空格,否则这个人很好。如果thread name包含空格,则将其拆分为两个参数,如下所示。

argv[1] -> pid
argv[2] -> thread name (first part)
argv[3] -> thread name (second part)
argv[4] -> signal number

那么我应该如何编写一个正确的逻辑来解析这些参数呢?我不能总是将argv [3]硬编码为信号编号。有通用的方法吗?

我看到的一个选项是最后保留线程名称。但我觉得应该有比这更好的解决方案。

有人可以建议。

4 个答案:

答案 0 :(得分:1)

如果您认为signal number始终是最后一次,只需访问argv[argc-1]

例如:

int pid, signal_number;

pid = atoi(argv[1]);
signal_number = atoi(argv[argc-1]);

// process name can be constructed from concatenating argv[2] to argv[argc-2]

答案 1 :(得分:1)

选项1:将核心模式更改为%p %s %e。由于%e是唯一可以替换为空格的东西,因此您可以简单地考虑 all 尾随参数(即argv[i]的{​​{1}})来弥补线程名称。

选项2:如果您有多个可以用空格替换的说明符(例如i > 2%e的重复实例),您可以为您的参数设置添加魔术分隔符,您希望永远不会作为线程名称的一部分出现,然后在迭代参数时查找这些:

%h

在线程名称中的任何空格都被规范化的意义上,这两个选项都不是完美的,因此您无法准确地重建实际名称。例如,您无法区分仅在嵌入的空格运行长度上不同的线程。

答案 2 :(得分:0)

什么阻止你做这样的事情?

int pid, signal_number;
char* thread_name;

pid = atoi(argv[1]);
if(argc == 4)
{
    thread_name = argv[2];
    signal_number = atoi(argv[3]);
}
else if(argc == 5)
{
    thread_name = malloc(strlen(argv[2]) + strlen(argv[3]) + 1); //leaks
    strcpy(thread_name, argv[2]);
    strcat(thread_name, argv[3]);
    signal_number = atoi(argv[4]);
}

不完整,因为如果您获得5个参数,仍然需要释放thread_name,但这并不是很复杂。

答案 3 :(得分:0)

// this is one way to read process command line arguments
// when the number of arguments (argc) can be 4 or 5

// argv[0] is always current pgm name and counts as any argument

if( 4 == argc ) { // process 3 arguments } 
else if( 5 == argc ) { // process 4 arguments }
else // unexpected argument list, handle error
endif

or

switch( argc )
{
    case 4:
    // call function to handle 3 arguments
    break;
    case 5: 
    // call function to handle 4 arguments
    break;
    default:
    // handle error condition
    break;
}