1

Тема: Сворення рядка і витягання чисел з нього

Доброї ночі маю ось таку задачу
"(1) Для виходу у Інтернет кожен комп’ютер отримує IP-адресу. Вона містить чотири цілих числа у діапазоні від 0 до 255, розділених крапками. Наприклад,
127.0.0.0
192.168.0.01
255.00.255.255
Написати програму, яка перевіряє чи введений рядок  є правильною IP-адресою.
"
Наприклад я ввів адресу 127.0.0.0, як я можу 127 зробити типом int? Чи можливо ви зможете підказати як правильніше робити перевірку.
Ip адресу записую в зміну типу

string

2

Re: Сворення рядка і витягання чисел з нього

shonrens написав:

Наприклад я ввів адресу 127.0.0.0, як я можу 127 зробити типом int?

Не знаю чи так правильно буде алей можна зробити структуру

struct IP
{
int field1,
field2,
field3,
field4;
};
...
IP ip1;
ip1.field1 = 127;
ip1.field2 = 0;
ip1.field3 = 0;
ip1.field4 = 0;
...

3

Re: Сворення рядка і витягання чисел з нього

вам про регулярки вже розповідали?

4

Re: Сворення рядка і витягання чисел з нього

FakiNyan написав:

вам про регулярки вже розповідали?

здається поки ні

5 Востаннє редагувалося shonrens (06.11.2015 01:25:19)

Re: Сворення рядка і витягання чисел з нього

Betterthanyou написав:
shonrens написав:

Наприклад я ввів адресу 127.0.0.0, як я можу 127 зробити типом int?

Не знаю чи так правильно буде алей можна зробити структуру

struct IP
{
int field1,
field2,
field3,
field4;
};
...
IP ip1;
ip1.field1 = 127;
ip1.field2 = 0;
ip1.field3 = 0;
ip1.field4 = 0;

Або я не розумію або я не правильно задав питання.
Наприклад в мене є string str = "127"; Потрібно ip1.field = str;

6

Re: Сворення рядка і витягання чисел з нього

shonrens написав:
FakiNyan написав:

вам про регулярки вже розповідали?

здається поки ні

то дуже крута штука, загугліть

7

Re: Сворення рядка і витягання чисел з нього

Без регулярних виразів теж не складно. Коротко один із примітивних алгоритмів:
1) перебираємо циклом усі символи в рядку, копіюємо у підрядок до зустрічі з крапкою або з кінцем рядка
2) коли зустріли крапку - те, що скопійовано в підрядку - має бути одне із 4-ох чисел - пробуємо його перевести в число і подивитися чи належить проміжку [0;255]
3) як тільки щось не так, можна відразу сміло переривати цикли, виходити з функції і казати, що то не валідний айпі, а якщо цикл пройшов успішно до кінця, то айпі - валідний

п.с. в неті є готові регулярні вирази для перевірки айпішок, але Вам ще не можна ними користуватися

Подякували: shonrens1

8

Re: Сворення рядка і витягання чисел з нього

Яб так робив:

bool IPCheck(char *s){
    int a[4];
    return sscanf(s,"%d.%d.%d.%d",&a[0],&a[1],&a[2],&a[3])==4 
        && (a[0]>=0 && a[0]<256)
        && (a[1]>=0 && a[1]<256)
        && (a[2]>=0 && a[2]<256)
        && (a[3]>=0 && a[3]<256)
    ;
}
Подякували: shonrens1

9

Re: Сворення рядка і витягання чисел з нього

Master_Sergius написав:

Без регулярних виразів теж не складно. Коротко один із примітивних алгоритмів:
1) перебираємо циклом усі символи в рядку, копіюємо у підрядок до зустрічі з крапкою або з кінцем рядка
2) коли зустріли крапку - те, що скопійовано в підрядку - має бути одне із 4-ох чисел - пробуємо його перевести в число і подивитися чи належить проміжку [0;255]
3) як тільки щось не так, можна відразу сміло переривати цикли, виходити з функції і казати, що то не валідний айпі, а якщо цикл пройшов успішно до кінця, то айпі - валідний

п.с. в неті є готові регулярні вирази для перевірки айпішок, але Вам ще не можна ними користуватися

Дуже дякую, буду пробувати.

10

Re: Сворення рядка і витягання чисел з нього

Itari написав:

Яб так робив:

bool IPCheck(char *s){
    int a[4];
    return sscanf(s,"%d.%d.%d.%d",&a[0],&a[1],&a[2],&a[3])==4 
        && (a[0]>=0 && a[0]<256)
        && (a[1]>=0 && a[1]<256)
        && (a[2]>=0 && a[2]<256)
        && (a[3]>=0 && a[3]<256)
    ;
}

я тут подумав був і зрозумів що переводити не обовязково)

11

Re: Сворення рядка і витягання чисел з нього

shonrens написав:
Itari написав:

Яб так робив:

bool IPCheck(char *s){
    int a[4];
    return sscanf(s,"%d.%d.%d.%d",&a[0],&a[1],&a[2],&a[3])==4 
        && (a[0]>=0 && a[0]<256)
        && (a[1]>=0 && a[1]<256)
        && (a[2]>=0 && a[2]<256)
        && (a[3]>=0 && a[3]<256)
    ;
}

я тут подумав був і зрозумів що переводити не обовязково)


А якщо буде введено десь не число, а якісь інші символи - це теж працюватиме? чи вилетить з помилкою?

Подякували: shonrens1

12

Re: Сворення рядка і витягання чисел з нього

Master_Sergius написав:
shonrens написав:
Itari написав:

Яб так робив:

bool IPCheck(char *s){
    int a[4];
    return sscanf(s,"%d.%d.%d.%d",&a[0],&a[1],&a[2],&a[3])==4 
        && (a[0]>=0 && a[0]<256)
        && (a[1]>=0 && a[1]<256)
        && (a[2]>=0 && a[2]<256)
        && (a[3]>=0 && a[3]<256)
    ;
}

я тут подумав був і зрозумів що переводити не обовязково)


А якщо буде введено десь не число, а якісь інші символи - це теж працюватиме? чи вилетить з помилкою?

хм, тобто якщо я візьму if (str <= 255 && str >= 0) нічого не вийде?

13

Re: Сворення рядка і витягання чисел з нього

str - це рядок. Як його можна порівнювати з числами?

Що важче - літр чи кілометр?

14 Востаннє редагувалося Itari (06.11.2015 14:17:31)

Re: Сворення рядка і витягання чисел з нього

shonrens написав:

зрозумів що переводити не обовязково)

Обов'язково.

це теж працюватиме? чи вилетить з помилкою?

Ця функція не вилітатиме з помилкою, вона лише скануе стрічку та переводить що зможе. Дальніше аналіз показує скільки скановано вірно, та знаходиться у потрібному диапазоні.

Подякували: shonrens1

15 Востаннє редагувалося Betterthanyou (06.11.2015 14:25:52)

Re: Сворення рядка і витягання чисел з нього

shonrens написав:
Betterthanyou написав:
shonrens написав:

Наприклад я ввів адресу 127.0.0.0, як я можу 127 зробити типом int?

Не знаю чи так правильно буде алей можна зробити структуру

struct IP
{
int field1,
field2,
field3,
field4;
};
...
IP ip1;
ip1.field1 = 127;
ip1.field2 = 0;
ip1.field3 = 0;
ip1.field4 = 0;

Або я не розумію або я не правильно задав питання.
Наприклад в мене є string str = "127"; Потрібно ip1.field = str;

наприклад так

#include <iostream>
#include <conio.h>
#include <string>

struct IP
{
private:
    int field1,
        field2,
        field3,
        field4;
public:
    IP(std::string str);
    void PrintIP();
    bool operator== (IP ip);
    void IpToInt(int *ip_field1, int *ip_field2, int *ip_field3, int *ip_field4);
};

IP::IP(std::string str = "0.0.0.0")
{
    std::string strcpy;

    int size = str.length();


    for (int i = 0, j = 0; i < size; i++)
    {
        if (str[i] != '.')
        {
            strcpy += str[i];
        }
        if (str[i] == '.' || i + 1 == size)
        {
            if (j == 0)
                field1 = atoi(strcpy.c_str());
            else if (j == 1)
                field2 = atoi(strcpy.c_str());
            else if (j == 2)
                field3 = atoi(strcpy.c_str());
            else if (j == 3)
                field4 = atoi(strcpy.c_str());
            j++;
            strcpy = "";
        }
    }

    if (field1 > 255 || field2 > 255 || field3 > 255 || field4 > 255)
    {
        field1 = 0, field2 = 0, field3 = 0, field4 = 0;
        std::cout << "Error! maximum ip 255.255.255.255" << std::endl;
    }

}

bool IP::operator== (IP ip)
{
    if (field1 == ip.field1 && field2 == ip.field2 && field3 == ip.field3 && field4 == ip.field4)
        return true;
    else
        return false;
}

void IP::PrintIP()
{
    std::cout << field1 << " " << field2 << " " << field3 << " " << field4 << std::endl;
}

void IP::IpToInt(int *ip_field1, int *ip_field2, int *ip_field3, int *ip_field4)
{
    *ip_field1 = field1;
    *ip_field2 = field2;
    *ip_field3 = field3;
    *ip_field4 = field4;
}

int main()
{

std::string str = "255.255.255.255";

std::cout << "--Initialization ip--" << std::endl << std::endl;

IP ip1 = str;
IP ip2 = (std::string)"127.0.0.0";
IP ip3 = (std::string)"192.168.0.01";
IP ip4 = (std::string)"255.00.255.255";
IP ip5 = (std::string)"255.255.255.256";

std::cout << "--Print ip--" << std::endl << std::endl;

ip1.PrintIP();
ip2.PrintIP();
ip3.PrintIP();
ip4.PrintIP();
ip5.PrintIP();

std::cout << "--Comparison ip--" << std::endl << std::endl;

std::cout << ((ip2 == ip5) ? "true" : "false") << std::endl;

int var1, var2, var3, var4;

std::cout << "--IpToInt ip--" << std::endl << std::endl;

ip2.IpToInt(&var1, &var2, &var3, &var4);


std::cout << var1 << " " << var2 << " " << var3 << " " << var4;



getch();
return 0;


}

--Initialization ip--
тут йде присвоєння IP структурі якщо воно більше за 255.255.255.255 виходить відповіде повідомлення про помилку
--Print ip--
тут виведення IP (там можна замінити " " на "." якщо потрібно через крапку)
--Comparison ip--
приклад порівняння Ip (Лише == , доробите по аналогії)
--IpToInt ip--
переведення ip в int (також можна так IP("255.60.255.255").IpToInt(&var1, &var2, &var3, &var4); тобто без створення об'єкта)

звичайно її потрібно дороблювати, ну я думаю ви зрозуміли мою ідею

Подякували: shonrens1

16 Востаннє редагувалося shonrens (06.11.2015 14:34:36)

Re: Сворення рядка і витягання чисел з нього

Betterthanyou написав:
shonrens написав:
Betterthanyou написав:

Не знаю чи так правильно буде алей можна зробити структуру

struct IP
{
int field1,
field2,
field3,
field4;
};
...
IP ip1;
ip1.field1 = 127;
ip1.field2 = 0;
ip1.field3 = 0;
ip1.field4 = 0;

Або я не розумію або я не правильно задав питання.
Наприклад в мене є string str = "127"; Потрібно ip1.field = str;

наприклад так

#include <iostream>
#include <conio.h>
#include <string>

struct IP
{
private:
    int field1,
        field2,
        field3,
        field4;
public:
    IP(std::string str);
    void PrintIP();
    bool operator== (IP ip);
    void IpToInt(int *ip_field1, int *ip_field2, int *ip_field3, int *ip_field4);
};

IP::IP(std::string str = "0.0.0.0")
{
    std::string strcpy;

    int size = str.length();


    for (int i = 0, j = 0; i < size; i++)
    {
        if (str[i] != '.')
        {
            strcpy += str[i];
        }
        if (str[i] == '.' || i + 1 == size)
        {
            if (j == 0)
                field1 = atoi(strcpy.c_str());
            else if (j == 1)
                field2 = atoi(strcpy.c_str());
            else if (j == 2)
                field3 = atoi(strcpy.c_str());
            else if (j == 3)
                field4 = atoi(strcpy.c_str());
            j++;
            strcpy = "";
        }
    }

    if (field1 > 255 || field2 > 255 || field3 > 255 || field4 > 255)
    {
        field1 = 0, field2 = 0, field3 = 0, field4 = 0;
        std::cout << "Error! maximum ip 255.255.255.255" << std::endl;
    }

}

bool IP::operator== (IP ip)
{
    if (field1 == ip.field1 && field2 == ip.field2 && field3 == ip.field3 && field4 == ip.field4)
        return true;
    else
        return false;
}

void IP::PrintIP()
{
    std::cout << field1 << " " << field2 << " " << field3 << " " << field4 << std::endl;
}

void IP::IpToInt(int *ip_field1, int *ip_field2, int *ip_field3, int *ip_field4)
{
    *ip_field1 = field1;
    *ip_field2 = field2;
    *ip_field3 = field3;
    *ip_field4 = field4;
}

int main()
{

std::string str = "255.255.255.255";

std::cout << "--Initialization ip--" << std::endl << std::endl;

IP ip1 = str;
IP ip2 = (std::string)"127.0.0.0";
IP ip3 = (std::string)"192.168.0.01";
IP ip4 = (std::string)"255.00.255.255";
IP ip5 = (std::string)"255.255.255.256";

std::cout << "--Print ip--" << std::endl << std::endl;

ip1.PrintIP();
ip2.PrintIP();
ip3.PrintIP();
ip4.PrintIP();
ip5.PrintIP();

std::cout << "--Comparison ip--" << std::endl << std::endl;

std::cout << ((ip2 == ip5) ? "true" : "false") << std::endl;

int var1, var2, var3, var4;

std::cout << "--IpToInt ip--" << std::endl << std::endl;

ip2.IpToInt(&var1, &var2, &var3, &var4);


std::cout << var1 << " " << var2 << " " << var3 << " " << var4;



getch();
return 0;


}

--Initialization ip--
тут йде присвоєння IP структурі якщо воно більше за 255.255.255.255 виходить відповіде повідомлення про помилку
--Print ip--
тут виведення IP (там можна замінити " " на "." якщо потрібно через крапку)
--Comparison ip--
приклад порівняння Ip (Лише == , доробите по аналогії)
--IpToInt ip--
переведення ip в int (також можна так IP("255.60.255.255").IpToInt(&var1, &var2, &var3, &var4); тобто без створення об'єкта)

звичайно її потрібно дороблювати, ну я думаю ви зрозуміли мою ідею

ми ще класи не вчили))) я тут пробував і помітив що елемент стрінг наприклад:
str[0]; можна перевести в чар а з чара в інт і таким чином я маю число і можу з ним робити перевірку...
Да мені тільки потрібно зрозуміти як я можу витягнути число )

17 Востаннє редагувалося Betterthanyou (06.11.2015 14:44:25)

Re: Сворення рядка і витягання чисел з нього

Прихований текст
shonrens написав:
Betterthanyou написав:
shonrens написав:

Або я не розумію або я не правильно задав питання.
Наприклад в мене є string str = "127"; Потрібно ip1.field = str;

наприклад так

#include <iostream>
#include <conio.h>
#include <string>

struct IP
{
private:
    int field1,
        field2,
        field3,
        field4;
public:
    IP(std::string str);
    void PrintIP();
    bool operator== (IP ip);
    void IpToInt(int *ip_field1, int *ip_field2, int *ip_field3, int *ip_field4);
};

IP::IP(std::string str = "0.0.0.0")
{
    std::string strcpy;

    int size = str.length();


    for (int i = 0, j = 0; i < size; i++)
    {
        if (str[i] != '.')
        {
            strcpy += str[i];
        }
        if (str[i] == '.' || i + 1 == size)
        {
            if (j == 0)
                field1 = atoi(strcpy.c_str());
            else if (j == 1)
                field2 = atoi(strcpy.c_str());
            else if (j == 2)
                field3 = atoi(strcpy.c_str());
            else if (j == 3)
                field4 = atoi(strcpy.c_str());
            j++;
            strcpy = "";
        }
    }

    if (field1 > 255 || field2 > 255 || field3 > 255 || field4 > 255)
    {
        field1 = 0, field2 = 0, field3 = 0, field4 = 0;
        std::cout << "Error! maximum ip 255.255.255.255" << std::endl;
    }

}

bool IP::operator== (IP ip)
{
    if (field1 == ip.field1 && field2 == ip.field2 && field3 == ip.field3 && field4 == ip.field4)
        return true;
    else
        return false;
}

void IP::PrintIP()
{
    std::cout << field1 << " " << field2 << " " << field3 << " " << field4 << std::endl;
}

void IP::IpToInt(int *ip_field1, int *ip_field2, int *ip_field3, int *ip_field4)
{
    *ip_field1 = field1;
    *ip_field2 = field2;
    *ip_field3 = field3;
    *ip_field4 = field4;
}

int main()
{

std::string str = "255.255.255.255";

std::cout << "--Initialization ip--" << std::endl << std::endl;

IP ip1 = str;
IP ip2 = (std::string)"127.0.0.0";
IP ip3 = (std::string)"192.168.0.01";
IP ip4 = (std::string)"255.00.255.255";
IP ip5 = (std::string)"255.255.255.256";

std::cout << "--Print ip--" << std::endl << std::endl;

ip1.PrintIP();
ip2.PrintIP();
ip3.PrintIP();
ip4.PrintIP();
ip5.PrintIP();

std::cout << "--Comparison ip--" << std::endl << std::endl;

std::cout << ((ip2 == ip5) ? "true" : "false") << std::endl;

int var1, var2, var3, var4;

std::cout << "--IpToInt ip--" << std::endl << std::endl;

ip2.IpToInt(&var1, &var2, &var3, &var4);


std::cout << var1 << " " << var2 << " " << var3 << " " << var4;



getch();
return 0;


}

--Initialization ip--
тут йде присвоєння IP структурі якщо воно більше за 255.255.255.255 виходить відповіде повідомлення про помилку
--Print ip--
тут виведення IP (там можна замінити " " на "." якщо потрібно через крапку)
--Comparison ip--
приклад порівняння Ip (Лише == , доробите по аналогії)
--IpToInt ip--
переведення ip в int (також можна так IP("255.60.255.255").IpToInt(&var1, &var2, &var3, &var4); тобто без створення об'єкта)

звичайно її потрібно дороблювати, ну я думаю ви зрозуміли мою ідею

ми ще класи не вчили))) я тут пробував і помітив що елемент стрінг наприклад:
str[0]; можна перевести в чар а з чара в інт і таким чином я маю число і можу з ним робити перевірку...
Да мені тільки потрібно зрозуміти як я можу витягнути число )

отак

#include <iostream>
#include <conio.h>
#include <string>

int main()
{
    std::string str = "127";
    int StrToInt = atoi(str.c_str());
    std::cout << StrToInt;

    getch();
    return 0;
}
Подякували: shonrens1

18

Re: Сворення рядка і витягання чисел з нього

Betterthanyou написав:

отак

#include <iostream>
#include <conio.h>
#include <string>

int main()
{
    std::string str = "127";
    int StrToInt = atoi(str.c_str());
    std::cout << StrToInt;

    getch();
    return 0;
}

мб те що треба) а для чого str.c_str()?

19

Re: Сворення рядка і витягання чисел з нього

shonrens написав:
Betterthanyou написав:

отак

#include <iostream>
#include <conio.h>
#include <string>

int main()
{
    std::string str = "127";
    int StrToInt = atoi(str.c_str());
    std::cout << StrToInt;

    getch();
    return 0;
}

мб те що треба) а для чого str.c_str()?

str.c_str() - перетворює string в char, а atoi перетворює char в int

20

Re: Сворення рядка і витягання чисел з нього

Betterthanyou написав:
shonrens написав:
Betterthanyou написав:

отак

#include <iostream>
#include <conio.h>
#include <string>

int main()
{
    std::string str = "127";
    int StrToInt = atoi(str.c_str());
    std::cout << StrToInt;

    getch();
    return 0;
}

мб те що треба) а для чого str.c_str()?

str.c_str() - перетворює string в char, а atoi перетворює char в int

зрозумів!!! Дуже дякую а то я вже був все почав прописувати і перетворювати))) я через vim пишу потрібно було ще підключити бібліотеку #include <cstdlib>