sscanf: разбор ip-адреса

Модератор: Модераторы разделов

IMB
Сообщения: 2567
ОС: Debian

sscanf: разбор ip-адреса

Сообщение IMB »

Доброго дня!
Требуется получить ip-адрес и заполнить им массив.

Код: Выделить всё

unsigned short    answer[ANSWER_MAX_LEN] = {0};
case COMMAND_NETWORK_GET_PARAM:
{
unsigned char    data[INET_ADDRSTRLEN];
struct in_addr    data_s;

data_s.s_addr = net_get_ifaddr("eth0");
inet_ntop(AF_INET, &data_s, data, INET_ADDRSTRLEN);
printf("data %s\n", data);
printf("sscanf %d\n", sscanf(data, "%3d.%3d.%3d.%3d",
    &answer[1], &answer[2], &answer[3], &answer[4]));
printf("%d %d %d %d\n", answer[1], answer[2], answer[3], answer[4]);

Вывод этого кода:

Код: Выделить всё

data 192.168.10.254
sscanf 4
0 10 0 254

Судя по выводу я успешно конвертирую полученный ip-адрес, sscanf находит все компоненты ip-адреса, но в массиве оказываются не все цифры, а те, что и попали в массив находятся не на своём месте.
В чём ошибка?

Ранее я уже использовал sscanf для разбора ip-адреса и таких сложностей не возникло.

Код: Выделить всё

case COMMAND_NETWORK_SET_GATEWAY:
if (sscanf(value, "%3d.%3d.%3d.%3d",
        &send[1], &send[2], &send[3], &send[4]) != 4)
{
    PARSE("%s", value);
    res = RESULT_DATA;
}
break;

Спасибо.
Спасибо сказали:
Аватара пользователя
rm_
Сообщения: 3340
Статус: It's the GNU Age
ОС: Debian

Re: sscanf: разбор ip-адреса

Сообщение rm_ »

Мой адрес - не дом и не улица, мой адрес 2001:470:989e::100.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: sscanf: разбор ip-адреса

Сообщение IMB »

В данном случае я работаю только с IPV4.
Спасибо сказали:
Аватара пользователя
Portnov
Модератор
Сообщения: 1786
Статус: Матёрый линуксоид
ОС: Debian testing/unstable

Re: sscanf: разбор ip-адреса

Сообщение Portnov »

Ну в «%3d» тройка явно лишняя, цифр там может быть любое количество.
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: sscanf: разбор ip-адреса

Сообщение IMB »

Portnov писал(а):
04.05.2011 15:36
Ну в «%3d» тройка явно лишняя, цифр там может быть любое количество.

Что значит любое количество, если я разбираю, для примера, 192.168.10.254?
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: sscanf: разбор ip-адреса

Сообщение IMB »

Разобрался, вся проблема была в несогласованности форматов.

Код: Выделить всё

unsigned short    answer[ANSWER_MAX_LEN] = {0};
....................
printf("sscanf %d\n", sscanf(data, "%3hd.%3hd.%3hd.%3hd",
    &answer[1], &answer[2], &answer[3], &answer[4]));
printf("%hd %hd %hd %hd\n", answer[1], answer[2], answer[3], answer[4]);
...........................

Вывод:

Код: Выделить всё

data 192.168.10.254
sscanf 4
192 168 10 254
Спасибо сказали:
Аватара пользователя
Portnov
Модератор
Сообщения: 1786
Статус: Матёрый линуксоид
ОС: Debian testing/unstable

Re: sscanf: разбор ip-адреса

Сообщение Portnov »

IMB писал(а):
04.05.2011 15:41
Что значит любое количество, если я разбираю, для примера, 192.168.10.254?

Ну, например, «10» — это не 3 цифры, а 2.
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: sscanf: разбор ip-адреса

Сообщение IMB »

Portnov писал(а):
04.05.2011 17:10
IMB писал(а):
04.05.2011 15:41
Что значит любое количество, если я разбираю, для примера, 192.168.10.254?

Ну, например, «10» — это не 3 цифры, а 2.

Справедливое замечание, но если я правильно понял документацию, то цифра в этом формате обозначает максимально количество значений которое можно считать, т.е. максимальную ширину поля. Таким образом указав %3d я сообщаю, что считать необходимо не более трёх цифр.

man 3 sscanf

..................... An optional decimal integer which specifies the maximum field width. Reading of characters stops either when this maximum is reached or when a non-matching character is found, whichever happens first. Most conversions discard initial white space characters (the exceptions are noted below), and these discarded characters don’t count towards the maximum field width. String input conversions store a null terminator ('\0') to mark the end of the input; the maximum field width does not include this terminator. ......................

Спасибо сказали:
adav84
Сообщения: 41

Re: sscanf: разбор ip-адреса

Сообщение adav84 »

man inet_addr ?
или (если чуствуете себя "суровым") - man flex / bison :))
Спасибо сказали:
frp
Сообщения: 1445
ОС: Debian Squeeze

Re: sscanf: разбор ip-адреса

Сообщение frp »

adav84 писал(а):
04.05.2011 17:41
man flex / bison

:D
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: sscanf: разбор ip-адреса

Сообщение IMB »

adav84 писал(а):
04.05.2011 17:41
man inet_addr ?

Простите, не уловил мысли, не затруднит расшифровать?
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5412
ОС: Gentoo

Re: sscanf: разбор ip-адреса

Сообщение /dev/random »

IMB писал(а):
04.05.2011 19:11
adav84 писал(а):
04.05.2011 17:41
man inet_addr ?

Простите, не уловил мысли, не затруднит расшифровать?

А что тут расшифровывать? Функция такая есть, inet_addr(). Документацию по ней можно вызвать командой man inet_addr. Она как раз парсит адрес из строки.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: sscanf: разбор ip-адреса

Сообщение IMB »

/dev/random писал(а):
04.05.2011 20:04
IMB писал(а):
04.05.2011 19:11
adav84 писал(а):
04.05.2011 17:41
man inet_addr ?

Простите, не уловил мысли, не затруднит расшифровать?

А что тут расшифровывать? Функция такая есть, inet_addr(). Документацию по ней можно вызвать командой man inet_addr. Она как раз парсит адрес из строки.

По-видимому у нас несколько различается документация.
В моей...

man inet_addr

INET(3) Linux Programmer's Manual INET(3) NAME inet_aton, inet_addr, inet_network, inet_ntoa, inet_makeaddr, inet_lnaof, inet_netof - Internet address manipulation routines .................... in_addr_t inet_addr(const char *cp); ................


Ничего эта фукция не парсит, он только приводит, если я правильно понимаю, к сетевому порядку.
Я там не вижу ни одной фукции способной распарсить ip-адрес, различные манипуляции по изменению сетевой/обычный порядок пожалуйста.
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5412
ОС: Gentoo

Re: sscanf: разбор ip-адреса

Сообщение /dev/random »

IMB писал(а):
04.05.2011 20:40

man inet_addr

.................... in_addr_t inet_addr(const char *cp); ................


Входное значение: строка. Выходное: in_addr_t, т.е. распарсенный адрес в бинарном виде. У вас такая же документация, как и у меня.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: sscanf: разбор ip-адреса

Сообщение IMB »

Хорошо, будем считать это распарсенным адресом.
Я не могу понять каким боком это относится к моей задаче? Хотя, можно попробовать "походить" по in_addr_t.
Спасибо, проверю.
Спасибо сказали:
Аватара пользователя
KiWi
Бывший модератор
Сообщения: 2521
Статус: статус, статус, статус

Re: sscanf: разбор ip-адреса

Сообщение KiWi »

IMB писал(а):
04.05.2011 21:09
Хорошо, будем считать это распарсенным адресом.
Я не могу понять каким боком это относится к моей задаче? Хотя, можно попробовать "походить" по in_addr_t.
Спасибо, проверю.

Зачем получать 4 числа, если можно сразу получить 32битное беззнаковое число, коим и является IP-адрес(и в таком виде с ним, кстати, легче работать)?
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: sscanf: разбор ip-адреса

Сообщение RasenHerz »

IMB,
Ваша проблема в том, что параметры, которые вы передаете для записи, должны быть указателями на целое (int *), чего требует формат %d. В вашем случае адреса (в которые вы записываете числа) перекрываются и данные портятся.

P.S. не заметил что ТС сам нашел причину ошибки.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: sscanf: разбор ip-адреса

Сообщение IMB »

KiWi писал(а):
04.05.2011 22:29
Зачем получать 4 числа, если можно сразу получить 32битное беззнаковое число, коим и является IP-адрес(и в таком виде с ним, кстати, легче работать)?

Требования реализуемого протокола.
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: sscanf: разбор ip-адреса

Сообщение RasenHerz »

IMB писал(а):
05.05.2011 09:05
KiWi писал(а):
04.05.2011 22:29
Зачем получать 4 числа, если можно сразу получить 32битное беззнаковое число, коим и является IP-адрес(и в таком виде с ним, кстати, легче работать)?

Требования реализуемого протокола.

Хранить IP адрес в виде одного числа, а не массива, удобнее если вдруг вам понадобится, к примеру, в какой-то функции обработать этот IP (IP-фильтр). Получение отдельных октетов тоже не будет проблемой.
Спасибо сказали: