我目前正在编写一个解析器来解析一个URL查询,例如key1=value1&key2=value2
。我得到第一个参数,但在第二个参数,它死了。这是我使用的精简代码:
const char *query_str = "key1=&key2=value2"
char *tmp, *value, *key;
int no_of_params = 2, value_str_len;
key = strdup(query_str);
for(; no_of_params > 0; no_of_params--)
{
tmp = strchr(key, '=');
printf("Currently at: %s/%s\n", key, tmp);
*tmp = '\0';
printf("Currently at: %s/%s\n", key, tmp);
tmp = tmp + 1;
value_str_len = tmp - strchr(tmp, '&') + 1;
value = malloc(value_str_len);
strncpy(value, tmp, value_str_len - 1);
value[value_str_len - 1] = '\0';
printf("Adding Key '%s' and Value '%s'\n", key, value);
free(value);
key = strchr(query_str, '&') + 1;
}
我希望我已经正确调整了一切。这实际上是一个更大的函数的一部分,但它应该类似于我使用的代码。这是运行时的输出:
Currently at: key1=&key2=value2/=&key2=value2
Currently at: key1/
Adding...
Adding Key 'key1' and Value ''
Currently at: key2=value2/=value2
然后发生分段错误。所以它显然是*tmp = '\0'
行,但为什么呢? (请注意,在实际代码中,每次打印后我flush(stdout)
,所以我现在就是这一行。)
我认为自从我之前的printf
工作以来,tmp
就是我所期望的,但是为什么这种技术只适用于第一次迭代而不适用于第二次迭代?
答案 0 :(得分:2)
除了Ganesh所说的,我还看到了行value_str_len = tmp - strchr(tmp, '&') + 1;
的问题。首先,strchr
应该找到超过tmp
的&符号,但是从tmp
(更小)中减去该指针值(通常会更大),可能会导致负长度。其次,你没有处理没有找到&符号的情况。是的,解析很棘手。祝你好运。
答案 1 :(得分:1)
query_str
的类型为const char *
,因此key = strchr(query_str, '&') + 1;
将失败。