2013-04-11 2 views
1

В настоящее время я пишу парсер для анализа запроса URL-адреса, например. key1=value1&key2=value2. Я получаю первый параметр, но на втором он умирает. Вот укороченный код, который я использую:URL-адрес Парсер запроса: Сегментация Ошибка во втором параметре

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

Я рекомендую запустить это в отладчике. Это должно точно показать, где это происходит, и почему. –

+0

Кроме того, если вы не хотите упражнения или не пишете что-либо, что будет сидеть в открытом Интернете, я рекомендую использовать проверенный код для синтаксического анализа строк запроса. С точки зрения безопасности, это чрезвычайно важная часть вашей программы. Для некоторых идей библиотеки взгляните на это: http://stackoverflow.com/questions/1192434/how-to-parse-a-url-in-c –

+0

@ RandallCook: Да, я просмотрел многие из них и попробовал их, но не соответствовал моим потребностям. Я уже написал это сам для самого URL. Кроме того, это не так критично, как вы думаете, так как вход контролируется, а использование в программе ограничено. – javex

ответ

1

query_str имеет тип const char * и, следовательно, key = strchr(query_str, '&') + 1; не удастся.

+0

Нет, это было случайное назначение 'key = strchr (query_str, '&') + 1;'. Поскольку 'query_str' является постоянным, назначение должно, конечно, терпеть неудачу. – javex

+0

@javex Я набрал этот ответ, прежде чем увидел ваш комментарий к 'query_str'. – Ganesh

2

В дополнение к тому, что говорит Ганеш, я вижу проблемы с линией value_str_len = tmp - strchr(tmp, '&') + 1;. Во-первых, strchr должен найти амперсанд за пределами tmp, но вы вычтите это значение указателя (которое обычно будет больше) от tmp (что меньше), что потенциально приведет к отрицательной длине. Во-вторых, вы не обрабатываете случай, когда амперсанд не найден. Да, разбор сложный. Удачи.

+0

Я также разделяю те же наблюдения. – Ganesh

+0

Вы были абсолютно правы. Я исправил эту ошибку, и теперь она работает плавно. Спасибо. – javex

Смежные вопросы