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 :)
Fórum › C / C++
C++ roztrhnutí IP
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
#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.
#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
}
}
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
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
#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");
}
//---------------------------------------------------------------------------
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
#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.
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
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:
#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
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
#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;
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;
}
}
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
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
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Nahrada za ip2long a long2ip — založil marioff
IPC - Memory Mapped File nebo Named Pipe? — založil hlucheucho
Hledám vývojáře pro iPhone aplikaci — založil Def
Měl by někdo zájem o HTC Diamond nebo iPod Touch 32GB? — založil Curo
Jak zalozit IPS (included private server) (WOW:WOTLK MaNGOS) — založil seventhsky@seznam.cz
Moderátoři diskuze