Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: проблема с функцией inet_ntoa()  (Прочитано 14449 раз)
0 Пользователей и 4 Гостей смотрят эту тему.
cishka
Гость
« : 27-02-2006 18:20 » 

изучаю STL решил поробовать написать код для работы с правилами айпи/маска и поместить их в вектор

вот код

Код:
#include <vector>
#include <iostream.h>
#include <conio.h>
#include <winsock2.h>

//---------------------------------------------------------------------------

typedef struct network {
    unsigned int ip;
    unsigned int mask;
} ip_addr;

int main(int argc, char* argv[])
{
using namespace std;
ip_addr net;
vector <ip_addr> v;
vector <ip_addr>::iterator k;
net.ip=inet_addr("192.168.1.1");net.mask=inet_addr("255.255.255.0");
v.push_back(net);

net.ip=inet_addr("192.168.1.2");net.mask=inet_addr("255.255.255.0");
v.push_back(net);
net.ip=inet_addr("192.168.1.30");net.mask=inet_addr("255.255.255.0");
v.push_back(net);
net.ip=inet_addr("192.168.1.4");net.mask=inet_addr("255.255.255.0");
v.push_back(net);
net.ip=inet_addr("192.168.1.5");net.mask=inet_addr("255.255.255.0");
v.push_back(net);
net.ip=inet_addr("192.168.1.40");net.mask=inet_addr("255.255.255.0");
v.push_back(net);
net.ip=inet_addr("192.168.1.701");net.mask=inet_addr("255.255.255.0");
v.push_back(net);

in_addr sa1;
in_addr sa2;
for (k=v.begin();k<v.end();k++)
    {
    net=*k;
    sa1.S_un.S_addr=net.ip;
    sa2.S_un.S_addr=net.mask;
    cout << inet_ntoa(sa1) << "   " << inet_ntoa(sa2) << "\n";
    }


getch();
    return 0;
}

в результате имею:

192.168.1.1   192.168.1.1
192.168.1.2   192.168.1.2
192.168.1.30   192.168.1.30
192.168.1.4   192.168.1.4
192.168.1.5   192.168.1.5
192.168.1.40   192.168.1.40
255.255.255.255   255.255.255.255

вот например другой вариант:

Код:
#include <vector>
#include <iostream.h>
#include <conio.h>
#include <winsock2.h>

//---------------------------------------------------------------------------

typedef struct network {
    unsigned int ip;
    unsigned int mask;
} ip_addr;

int main(int argc, char* argv[])
{
using namespace std;
ip_addr net;
vector <ip_addr> v;
vector <ip_addr>::iterator k;
net.ip=inet_addr("192.168.1.1");net.mask=inet_addr("255.255.255.0");
v.push_back(net);

net.ip=inet_addr("192.168.1.2");net.mask=inet_addr("255.255.255.0");
v.push_back(net);
net.ip=inet_addr("192.168.1.30");net.mask=inet_addr("255.255.255.0");
v.push_back(net);
net.ip=inet_addr("192.168.1.4");net.mask=inet_addr("255.255.255.0");
v.push_back(net);
net.ip=inet_addr("192.168.1.5");net.mask=inet_addr("255.255.255.0");
v.push_back(net);
net.ip=inet_addr("192.168.1.40");net.mask=inet_addr("255.255.255.0");
v.push_back(net);
net.ip=inet_addr("192.168.1.701");net.mask=inet_addr("255.255.255.0");
v.push_back(net);

in_addr sa1;
in_addr sa2;
for (k=v.begin();k<v.end();k++)
    {
    net=*k;
    sa1.S_un.S_addr=net.ip;
    sa2.S_un.S_addr=net.mask;
    cout << net.ip << "   " << inet_ntoa(sa2) << "\n";
    }


getch();
    return 0;
}


вот результат:

16885952   255.255.255.0
33663168   255.255.255.0
503425216   255.255.255.0
67217600   255.255.255.0
83994816   255.255.255.0
671197376   255.255.255.0
4294967295   255.255.255.0

т.е. проблема в inet_ntoa ? кто знает что происходит ? как это понимать... и как это вылечить ?
Записан
cishka
Гость
« Ответ #1 : 27-02-2006 19:30 » 

опечатался....

net.ip=inet_addr("192.168.1.701");net.mask=inet_addr("255.255.255.0");
v.push_back(net);

должно быть 192.168.1.70

но результат все равно тотже
Записан
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 28-02-2006 05:51 » 

в результате имею:

192.168.1.1   192.168.1.1
192.168.1.2   192.168.1.2
192.168.1.30   192.168.1.30
192.168.1.4   192.168.1.4
192.168.1.5   192.168.1.5
192.168.1.40   192.168.1.40
255.255.255.255   255.255.255.255

Если я правильно понял, то ты ожидаешь увидеть на экране:

192.168.1.1   255.255.255.0
192.168.1.2   255.255.255.0
192.168.1.30   255.255.255.0
192.168.1.4   255.255.255.0
192.168.1.5   255.255.255.0
192.168.1.40   255.255.255.0
192.168.1.70   255.255.255.0

Если да, то проблема в том, что inet_ntoa возвращает указатель на внутренний статический буфер, поэтому строка
Код:
cout << inet_ntoa(sa1) << "   " << inet_ntoa(sa2) << "\n";
дает ошибку. То есть результат первого вызова inet_ntoa сразу же затирается результатом второго вызова.

Нужно так:
Код:
cout << inet_ntoa(sa1) << "   ";
cout << inet_ntoa(sa2) << endl;
Записан
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 28-02-2006 10:12 » 

Читаем документацию на inet_ntoa:
Цитата: man inet_ntoa
The inet_ntoa() function converts the Internet host address in given in network byte order to a string in standard numbers-and-dots notation.  The string is returned in a statically allocated buffer, which subsequent calls will overwrite.

Так как оператор << может не копировать содержимое строки в буфер, а запоминать указатель, то в результате получается то, что получается.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
cishka
Гость
« Ответ #4 : 28-02-2006 12:19 » 

Спасибо большое! теперь все понял! 

заменил на вот так
Код:
in_addr sa1;
in_addr sa2;
char *s1=new char[100];
char *s2=new char[100];
for (k=v.begin();k<v.end();k++)
    {
    net=*k;
    sa1.S_un.S_addr=net.ip;
    sa2.S_un.S_addr=net.mask;
    s1=strcpy(s1,inet_ntoa(sa1));
    s2=strcpy(s2,inet_ntoa(sa2));
    cout << s1 << "   " << s2 << "\n";
    }
delete s1,s2;

Записан
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 28-02-2006 12:30 » new

Хм... Динамическое выделение памяти + два вызова копирования строки на каждой итерации. Зачем?

Чем тебя вот этот вариант не устроил?
Код:
cout << inet_ntoa(sa1) << "   ";
cout << inet_ntoa(sa2) << endl;
« Последнее редактирование: 28-02-2006 12:31 от Hooter » Записан
cishka
Гость
« Ответ #6 : 28-02-2006 12:47 » 

да всем устроил, это уже просто извращенья Улыбаюсь
Записан
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 28-02-2006 12:53 » 

Ясно, извини Улыбаюсь
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines