C++ roztrhnutí IP – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

C++ roztrhnutí IP – C / C++ – Fórum – Programujte.comC++ roztrhnutí IP – C / C++ – Fórum – Programujte.com

 

Tomáš
~ Anonymní uživatel
560 příspěvků
23. 5. 2016   #1
-
0
-

Zdravím, programuji pingovací utilitku, ale mám problém v tom, když zadám např.: 10.1.140.1/27 jak tuto IP pomocí stringu roztrhnout na string 10 , 1, 140, 1, 27, každé číslo zvlášť... Předem díky za odpovědi :)

Nahlásit jako SPAM
IP: 109.71.213.–
KIIV
~ Moderátor
+43
God of flame
23. 5. 2016   #2
-
0
-

Muzes pouzit treba boost::split (pokud uz boost mas), nebo si to parsuj sam. String je jen slozenina ze znaku a k tem se da dostat bez problemu.

Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Tomáš
~ Anonymní uživatel
560 příspěvků
23. 5. 2016   #3
-
0
-

#2 KIIV
Nemohl by jsi mi s tím kódem trošku pomoct? :) Jsem úplný začátečník.

Nahlásit jako SPAM
IP: 109.71.213.–
KIIV
~ Moderátor
+43
God of flame
23. 5. 2016   #4
-
0
-

 No jak chces :DDD  Good luck with that :)

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>

void na_mezery(char & znak) {
  if (znak == '.' || znak == '/') znak = ' ';
}


int main() {
    std::string test("10.10.20.1/27");

    // nahradim '.' a '/' za mezery, at se to da prohnat istringstreamem:
    std::for_each(test.begin(), test.end(), &na_mezery);

    // Promenne
    std::istringstream in(test);
    std::vector<int> hodnoty;

    // zkopirujeme vsechny hodnoty z istrinstreamu do vectoru pomoci back_inserteru
    std::copy(
        std::istream_iterator<int>(in), std::istream_iterator<int>(),
        std::back_inserter(hodnoty)
        );

    // vypsat pole:
    std::copy(hodnoty.begin(), hodnoty.end(), std::ostream_iterator<int>(std::cout, " a "));
    std::cout << "\n";
}

Pouzivam hodne algoritmy, cim min toho clovek programuje sam, tim mene chyb se da nasekat

Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Tomáš
~ Anonymní uživatel
560 příspěvků
23. 5. 2016   #5
-
0
-

#4 KIIV
Tohle funguje hezky :D Celkem se i orientuju, ale potřebuju mít každou tu hodnotu zvlášť, protože pomocí masky je třeba spočítat cidr a pingovat rozsah, takže by bylo fajn, aby každý z toho čísla byla samostatná proměnná. + je to v broland c++ builderu, to jsem měl asi říct na začátku :D Vážně děkuju za pomoc :( Mám funkční variantu, kde vlastně byla každá část IP v samostatném editu, ale je třeba to dát do jednoho. Jde to nějak takhle roztrhnout? :)

#2 KIIV
Nemohl by jsi mi s tím kódem trošku pomoct? :) Jsem úplný začátečník.

Nahlásit jako SPAM
IP: 109.71.213.–
KIIV
~ Moderátor
+43
God of flame
23. 5. 2016   #6
-
0
-

   

#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>

void na_mezery(char & znak) {
  if (znak == '.' || znak == '/') znak = ' ';
}


int main() {
    std::string test("10.10.20.1/27");

    // nahradim '.' a '/' za mezery, at se to da prohnat istringstreamem:
    std::for_each(test.begin(), test.end(), &na_mezery);

    // Promenne
    std::istringstream in(test);

    int h1,h2,h3,h4,m;
    if( in >> h1 >> h2 >> h3 >> h4 >> m ) {
        // zobrazit kdo vi kam (do editu se musi prevest na string?)
        // pri chybe se sem nedostanes
    }
}
Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Tomáš
~ Anonymní uživatel
560 příspěvků
23. 5. 2016   #7
-
0
-

#6 KIIV
To moc nefunguje :/ https://ctrlv.cz/odqS

Nahlásit jako SPAM
IP: 109.71.213.–
KIIV
~ Moderátor
+43
God of flame
23. 5. 2016   #8
-
0
-

protoze si to nacpal do jine funkce... ja to delal jako samostatny program pro demonstraci, ze to jede, ne jako kus kodu, kterej nekam vlepis doprostred kdoviceho

Nahlásit jako SPAM
IP: 212.47.3.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Tomáš
~ Anonymní uživatel
560 příspěvků
23. 5. 2016   #9
-
0
-

#8 KIIV
Je to v novym čistym borland souboru, pod button click akci a jediný co jsem dopsal, aby se první proměnná hodila do Labelu, jestli to funguje, ale má to někde problém, že se to nespustí

Nahlásit jako SPAM
IP: 109.71.213.–
23. 5. 2016   #10
-
0
-

Zkus sem plácnout co máš. Jinak u C++ Builderu by to šlo dělat s použitím třídy TSringList. Řetězec vložíš do vlastnosti DelimitedText, oddělovač dáš do Delimiter a tokeny čteš jako pole. Všechno je to UnicodeString. Konverze na čísla pak pomocí metody ToInd (metoda třídy UnicodeString). Nevýhodou je, že to musíš udělat 2x: poprvé za použití . (tečky) jako oddělovače a podruhé jen pro poslední token za použití / jako oddělovače.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Tomáš
~ Anonymní uživatel
560 příspěvků
23. 5. 2016   #11
-
0
-

#10 hlucheucho 

Takhle je to funkční, ale každá část IP je v jiném editu, potřebuju to napsat do jednoho a rozdělit.

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

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <stdio.h>
#include <conio.h>
#include <string>
#include <windows.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

TForm1 *Form1;
FILE *sou;
FILE *vys;
int n=0,rozsah=2,sta=1;
char slovo[20],slovo1[20]="bajty=32";



//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  vys=fopen("vysledek.txt","w");
     sta=StrToInt(Edit4->Text);
     rozsah=2;
n=32-StrToInt(Edit5->Text);

        for(int i=1; i<n; i++){
	rozsah=rozsah*2;
        }
        rozsah=rozsah+StrToInt(Edit4->Text);


        for(int i=StrToInt(Edit4->Text); i<rozsah; i++){
  if(i<=255)
  {
  Label8->Caption=sta;
  Refresh();
  system(("ping " + Edit1->Text +"." +Edit2->Text+ "." +Edit3->Text+"."+i + " -n 1" + " -w 10 > data.txt" ).c_str());

          sou=fopen("data.txt","r");

    while (!feof(sou))
          {
          fscanf(sou,"%s",&slovo);
          if(!feof(sou))
                         {
                         if (strcmpi(slovo1,slovo)==0)

                           fprintf(vys,"Stanice %i ... OK\n",sta);
                         }

          }
          sta=sta+1;
          fclose(sou);
         }
     }
     fclose(vys);
     Memo1->Lines->LoadFromFile("vysledek.txt");

     }



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


Nahlásit jako SPAM
IP: 109.71.213.–
23. 5. 2016   #12
-
0
-

Možná by ti pomohlo místo obyčejného EditText použít MaskEdit. Ten umožňuje nastavit striktně formát zadání což by možná tady bylo lepší.

Cokoliv, co se v Editu zobrazuje je v jeho vlastnosti Text, která je UnicodeString. Pokud chceš zadanou IP rozebrat na části, použiješ Edit->Text jako StringList->DelimitedText a přečeteš tokeny ze StringListu. Pokud naopak chceš IP poskládat z jejích částí, naskládáš ji jako tokeny do StringListu a výsledek bude v StringList->DelimitedText, ten pak zkopírueš do Edit->Text.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Tomáš
~ Anonymní uživatel
560 příspěvků
23. 5. 2016   #13
-
0
-

#12 hlucheucho
Nebyl by jsi ochotný mi to pomoct dát dohromady? :D Jsem ve druháku a s buildrem jsme dávno skončili vážně se základama... Dnešekm nad tím budu mít 30h na praxích se spolužákem, snažili jsme se to vymyslet/vygooglit a dát dohromady samy, ale už si vážně nevíme rady... Byl by jsem za pomoc se složením toho kódu vážně vděčný... Můžu sem hodit odkaz na celý projekt třeba v raru.

Nahlásit jako SPAM
IP: 109.71.213.–
23. 5. 2016   #14
-
0
-

 Pro rozdělení IP ve tvaru 255.48.87.138 na části:

UnicodeString castiIP[4];
TStringList *StringList = new TStringList();
StringList->DelimitedText = Edit->Text; //Edit obsahuje celou IP, pro zjednoduseni bez portu
StringList->Delimiter = '.';
For(int i = 0; i < StringList->Count; i++)
{
   castiIP[i] = StringList->Strings[i];
   //namisto kopirovani s castmi IP udelas co potrebujes
}

hu

Nahlásit jako SPAM
IP: 195.178.67.–
vitamin+8
Grafoman
23. 5. 2016   #15
-
0
-

Co tak skusit pouzit boost asio? Vie aj parsovat ipv4 link

Nahlásit jako SPAM
IP: 195.28.77.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Tomáš
~ Anonymní uživatel
560 příspěvků
23. 5. 2016   #16
-
0
-

#14 hlucheucho
Takže chápu dobře, že ten castiIP[1] bude číslo před první tečkou? Jestli jo, tak je to vážně super :) Teď ještě jak z toho dostat masku za lomítkem... :D Vážně díky :)

Nahlásit jako SPAM
IP: 109.71.213.–
23. 5. 2016   #17
-
0
-

   

OddelPort->DelimitedText = Edit->Text; //Edit obsahuje celou IP
OddelPort->Delimiter = '/';
if(OddelPort->Count = 2)
{
   //v OddelPort->Strings[1] je port jako UnicodeString
}
StringList->DelimitedText = OddelPort->Strings[0]
StringList->Delimiter = '.';
For(int i = 0; i < StringList->Count; i++)
{
   //casti IP jsou ve StringList->Strings[i];
}


hu

Pokud by měl být za lomítkem port, tak bych na to šel takto:

Nahlásit jako SPAM
IP: 195.178.67.–
Tomáš
~ Anonymní uživatel
560 příspěvků
23. 5. 2016   #18
-
0
-

#17 hlucheucho
Takže části IP najdu pod StringList->Strings[i] a ten port kde? To je poslední dotaz, vážně jsi mi pomohl :)

Nahlásit jako SPAM
IP: 109.71.213.–
23. 5. 2016   #19
-
0
-

#16 Tomáš
Pole se indexují od 0. První privek je tedy castiIP[0] což je prvním číslem IP adresy, poslední pak bude v castiIP[3]. Pokud zkusíš castiIP[4] měl bys obdržet vyjímku Acces Violation at Adress ...  Akorát to máš jako UnicodeString. Pokud chceš číslo, musíš pro konverzi volat metodu ToInt()

hu
 

Nahlásit jako SPAM
IP: 195.178.67.–
23. 5. 2016   #20
-
0
-

#18 Tomáš
Port až u druhé verze, je to v komentáři v podmínce if. První ukázka ho neuměla.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Tomáš
~ Anonymní uživatel
560 příspěvků
23. 5. 2016   #21
-
0
-

#20 hlucheucho
Díky moc, jdu to zkusit dát dohromady :) Kdyžtak se ozvu :P

Nahlásit jako SPAM
IP: 109.71.213.–
23. 5. 2016   #22
-
0
-

#15 vitamin
Nevím, zda je součástí C++ Builderu a nakolik je s ním kompatibilní.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
23. 5. 2016   #23
-
0
-

#21 Tomáš
Snad v tom nebude moc chyb, C++ Builder jsem opustil před 3/4 rokem a tak se jeho znalosti zvolna vytrácejí. Možná narazíš u (hodně) starších verzí na AnsiString. Funkce však zůstavá stejná.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Tomáš
~ Anonymní uživatel
560 příspěvků
23. 5. 2016   #24
-
0
-

Zavedení všech proměných do svýho programu jsem zvládl, ale je tu pár chybiček, se kterýma nevim co s nima, nebude třeba nějaký ten stringlist zadefinovat? https://ctrlv.cz/GNUY

Připojen obrázek.

Nahlásit jako SPAM
IP: 109.71.213.–
23. 5. 2016   #25
-
0
-

#24 Tomáš
Každá metoda se chová jako funkce a spolu s tím platí i pravidla o viditelnosti proměnných. Zde bych doporučil použít lokální proměnné, tzn. jejich deklarace a inicializace v těle funkce nebo metody kde se použijí. Použití TStringList *jmeno = new TStringList; na začátku funkce nebo metody to řeší. Ještě je potřeba před návratem funkce nebo metody objekt uvolnit pomocí delete, protože fukce při svém návratu odstraní jen ukazatel, neuvolní paměť na kterou ukazuje.

hu

Edit: Se mi z ukázky ty inicializace vytratily. Měly by vypadat takto: 

TStringList *StringList = new TStringList();
TStringList *OddelPort = new TStringList();


uvolnění objektu pak:

delete StringList;
delete OddelPort;
Nahlásit jako SPAM
IP: 195.178.67.–
Tomáš
~ Anonymní uživatel
560 příspěvků
24. 5. 2016   #26
-
0
-

Tak jsem to vyřešil takhle a funguje to náramně :3

strcpy(ret,Edit1->Text.c_str());

         for (int i=0; i<=20;i++)  {

    if ((ret[i]=='0')||(ret[i]=='1')||(ret[i]=='2')||(ret[i]=='3')||(ret[i]=='4')||(ret[i]=='5')||(ret[i]=='6')||(ret[i]=='7')||(ret[i]=='8')||(ret[i]=='9'))
    {
    ret2[x]=ret[i];
    x++;
    }
     else
     {
     x=i;
     i=20;
     }
    }
 x=x+1;
    //------------------------------------------------

    for (int i=x; i<=20;i++)  {

    if ((ret[i]=='0')||(ret[i]=='1')||(ret[i]=='2')||(ret[i]=='3')||(ret[i]=='4')||(ret[i]=='5')||(ret[i]=='6')||(ret[i]=='7')||(ret[i]=='8')||(ret[i]=='9'))
    {
    ret3[y]=ret[i];
    y++;
    }
    else
     {
     y=i;
     i=20;
     }
    }
   y=y+1;
   x=0;

  //------------------------------------------------
   for (int i=y; i<=20;i++)  {

    if ((ret[i]=='0')||(ret[i]=='1')||(ret[i]=='2')||(ret[i]=='3')||(ret[i]=='4')||(ret[i]=='5')||(ret[i]=='6')||(ret[i]=='7')||(ret[i]=='8')||(ret[i]=='9'))
    {
    ret4[x]=ret[i];
    x++;
    }
    else
     {
     x=i;
     i=20;
     }
    }
   x=x+1;

   y=0;
    //------------------------------------------------
   for (int i=x; i<=20;i++)  {

    if ((ret[i]=='0')||(ret[i]=='1')||(ret[i]=='2')||(ret[i]=='3')||(ret[i]=='4')||(ret[i]=='5')||(ret[i]=='6')||(ret[i]=='7')||(ret[i]=='8')||(ret[i]=='9'))
    {
    ret5[y]=ret[i];
    y++;
    }
    else
     {
     y=i;
     i=20;
     }
    }
   y=y+1;
   x=0;
    //------------------------------------------------
   for (int i=y; i<=20;i++)  {

    if ((ret[i]=='0')||(ret[i]=='1')||(ret[i]=='2')||(ret[i]=='3')||(ret[i]=='4')||(ret[i]=='5')||(ret[i]=='6')||(ret[i]=='7')||(ret[i]=='8')||(ret[i]=='9'))
    {
    ret6[x]=ret[i];
    x++;
    }
    else
     {
     x=i;
     i=20;
     }
    }
Nahlásit jako SPAM
IP: 109.71.213.–
24. 5. 2016   #27
-
0
-

U novějších verzí C++ Builderu bys s tím nepochodil. Funkce c_str() pro převod na char* fungovala u AnsiStringu.

Kromě toho ta šílená podmínka... používá se if((neco >= '0') && (neco <= '9')). Jak jsem psal, pokud chceš čísla, stačí na jednotlivých UnicodeString tokenech zavolat metodu ToInt: 


int port;
int ip[4];

TStringList *StringList = new TStringList();
TStringList *OddelPort = new TStringList();

OddelPort->DelimitedText = Edit->Text; //Edit obsahuje celou IP
OddelPort->Delimiter = '/';
if(OddelPort->Count = 2)
{
   //v OddelPort->Strings[1] je port jako UnicodeString
   port = OddelPort->Strings[1].ToInt();
}
StringList->DelimitedText = OddelPort->Strings[0]
StringList->Delimiter = '.';
For(int i = 0; i < StringList->Count; i++)
{
   //casti IP jsou ve StringList->Strings[i];
   ip[i] = StringList->Strings[i].ToInt();
}

delete StringList;
delete OddelPort;


navzdory volným řádkům jsem napsal ani nepolovinu objemu kódu. Čím méně svého vlastního kódu napíšeš, tím menší pravděpodobnost chyb (autor výroku se přihlásí o svá práva).

hu

Nahlásit jako SPAM
IP: 195.178.67.–
24. 5. 2016   #28
-
0
-

Ještě pozn.: pokud bys chtěl zpracovat char*, stačí použít strtok a každý token konvertovat pomocí atoi. Když pohledáš na msdn najdeš i Thread Safe provedení strtok.

hu

Edit: doplním k funkci c_str(): pro UnicodeString k převodu na char* sloužila metoda t_str(). U nových verzí (např XE5) se její použití nedoporučuje a převod na char* se musí dělat dost kostrbatě přes AnsiString, vypadá to takhle: 

char text[256];

strcpy(text, AnsiString(Edit1->Text).c_str();


Textové vlastnosti jsou UnicodeString už docela dlouho.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 94 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý