Как получить подстроку, лежащую между двумя подстроками в C? - PullRequest
0 голосов
/ 17 января 2010

У меня есть код захвата пакета, который записывает полезную нагрузку http в файл. Теперь я хочу извлечь информацию об URL из этих дампов. Для каждого пакета полезная нагрузка начинается следующим образом.

GET /intl/en_com/images/logo_plain.png HTTP / 1.1..Host: www.google.co.in..User-Agent: Mozilla / 5.0

Я хотел бы извлечь:

  1. строка между "GET" и "HTTP / 1.1"
  2. строка между "Host:" и "User-Agent"

Как это сделать в C? Есть ли встроенные строковые функции? Или регулярные выражения?

Ответы [ 2 ]

2 голосов
/ 17 января 2010

C не имеет встроенных регулярных выражений, хотя библиотеки доступны: http://www.arglist.com/regex/, http://www.pcre.org/ - это два, которые я вижу чаще всего.

Для такой простой задачи вы можете легко уйти, не используя регулярные выражения. Если все строки меньше максимальной длины MAXLEN, просто обрабатывайте их по одной строке за раз:

char buf[MAXLEN];
char url[MAXLEN];
char host[MAXLEN];
int state = 0;      /* 0: Haven't seen GET yet; 1: haven't seen Host yet */
FILE *f = fopen("my_input_file", "rb");

if (!f) {
    report_error_somehow();
}

while (fgets(buf, sizeof buf, f)) {
    /* Strip trailing \r and \n */
    int len = strlen(buf);
    if (len >= 2 && buf[len - 1] == '\n' && buf[len - 2] == '\r') {
        buf[len - 2] = 0;
    } else {
        if (feof(f)) {
            /* Last line was not \r\n-terminated: probably OK to ignore */
        } else {
            /* Either the line was too long, or ends with \n but not \r\n. */
            report_error_somehow();
        }
    }

    if (state == 0 && !memcmp(buf, "GET ", 4)) {
        strcpy(url, buf + 4);    /* We know url[] is big enough */
        ++state;
    } else if (state == 1 && !memcmp(buf, "Host: ", 6)) {
        strcpy(host, buf + 6);   /* We know host[] is big enough */
        break;
    }
}

fclose(f);

Это решение не требует буферизации всего файла в памяти, как ответ KennyTM (хотя, кстати, это хорошо, если вы знаете, что файлы маленькие). Обратите внимание, что мы используем fgets() вместо небезопасного gets(), который склонен к переполнению буферов на длинных строках.

1 голос
/ 17 января 2010

Найдите местоположение \r, используя strchr (или strstr). Поскольку строки GET и HTTP/1.1 и Host: имеют фиксированную длину, индекс и местоположение пути между ними можно легко извлечь.


Если вы хотите использовать регулярные выражения, в POSIX-совместимых системах есть regcomp(3), но это также довольно сложно использовать.

...