2010-05-13 2 views
2

Я должен разобрать эту строку в C:Самый простой способ разобрать строку в C?

XFR 3 NS 207.46.106.118:1863 0 207.46.104.20:1863\r\n 

И быть в состоянии получить 207.46.106.118 часть и 1863 часть (первый IP-адрес).

Я знаю, что мог бы использовать char по char и, в конце концов, найти свой путь через него, но какой самый простой способ получить эту информацию, учитывая, что IP-адрес в строке может измениться на другой формат (с меньшим количеством цифр)?

+0

Можно ли использовать регулярное выражение в C? –

+0

Я не хочу использовать библиотеку регулярных выражений только для этой задачи. –

+2

Простейший и самый точный может быть не то же самое ... –

ответ

11

Вы можете использовать sscanf() из стандартной библиотеки C. Вот пример того, как получить IP-адрес и порт в виде строк, принимая участие в передней части адреса постоянна:

#include <stdio.h> 

int main(void) 
{ 
    const char *input = "XFR 3 NS 207.46.106.118:1863 0 207.46.104.20:1863\r\n"; 

    const char *format = "XFR 3 NS %15[0-9.]:%5[0-9]"; 
    char ip[16] = { 0 }; // ip4 addresses have max len 15 
    char port[6] = { 0 }; // port numbers are 16bit, ie 5 digits max 

    if(sscanf(input, format, ip, port) != 2) 
     puts("parsing failed"); 
    else printf("ip = %s\nport = %s\n", ip, port); 

    return 0; 
} 

важные части строк формата являются набор сканируемых символов модели %15[0-9.] и %5[0-9], который будет соответствовать строка из не более 15 символов, состоящая из цифр или точек (т. е. IP-адреса не будут проверяться на корректность), а строка не более 5 цифр соответственно (что означает, что недопустимые номера портов выше 2^16-1 проскальзывают).

+0

все, кроме IP-адресов и номеров портов. IP-адрес может измениться (больше/меньше цифр) ... так же, как и с портом. –

+0

@Luca: вы хотите получить ip-адрес/порт как строки или целые числа? вам все равно, если остальная часть строки хорошо сформирована или вас интересует только первый ip-адрес? – Christoph

+0

да, мне нужен адрес и порт как строки. не заботятся обо всем остальном. –

2

В зависимости от того, что определяет формат документа. В этом случае это может быть так же просто, как tokenizing the string и смотреть через токены за то, что вы хотите. Просто используйте strtok и разделите на пробелы, чтобы захватить 207.46.106.118:1863, а затем вы можете tokenize это снова (или просто сканировать для : вручную), чтобы получить правильные компоненты.

2

Вы можете использовать strtok для того, чтобы разблокировать прорыв в космосе, или вы могли бы использовать один из семейства scanf, чтобы вытащить данные.

Во всем этом есть большой оговорка, но это функции, которые печально известны своей безопасностью и неправильным обращением. YMMV.

0

Если строки, которые должны быть проанализированы, хорошо отформатированы, я бы пошел с предложением Даниэля и Укко использовать strtok().

Слово предупреждения, хотя: strtok() изменяет строку, которую он анализирует. Не всегда то, что вы хотите.

1

В этом случае strok() имеет тривиальное использование и будет моим выбором. В целях безопасности вы можете подсчитать ':' в своей строке и продолжить, если есть ровно один:.

2

Прокрутите до тех пор, пока вы не получите первый «.», И обведите назад, пока не найдете «». Цикл вперед, пока вы не найдете «:», строя подстроки каждый раз, когда вы встретитесь ». или ':'. Вы можете проверить количество подстрок и их длину как простую проверку ошибок. Затем залейте петлю, пока не найдете «', и у вас есть часть 1863 года.

Это было бы здорово, если начало строки не сильно отличается. А также очень легко. Вы можете сделать это еще проще, если строка всегда начинается с «XFR 3 NS».

0

Это может быть излишним, поскольку вы сказали, что не хотите использовать библиотеку регулярных выражений, но программа re2c даст вам регулярное выражение без библиотеки: оно генерирует DFSM для регулярного выражения как код C. Регулярные выражения указаны в комментариях, встроенных в код C.

И что кажется излишним, теперь может стать для вас комфортом, если вам придется разбирать остальную часть строки; гораздо легче изменить несколько регулярных выражений, чтобы настроить или добавить новый синтаксис, чем изменить кучу специального кода токенизации. И это делает структуру того, что вы анализируете намного более четко в своем коде.