Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it
    Registrato dal
    Aug 2010
    Messaggi
    25

    [C++] Aiuto con i templates

    Ciao a tutti,
    oggi ho cominciato ad usare i templates del c++, in particolare set. Quello che voglio fare una lista di indirizzi ip, e ogni volta che ne ho uno nuovo vedere se esiste o no, in caso non esistesse devo aggiungerlo.
    Ora, riduco tutto il codice alla parte che mi interessa:
    codice:
    #include <set>
    #include <iostream>
    #include <iterator>
    
    using namespace std;
    
    typedef char FLOWID[8]
    
    typedef set <FLOWID> IDF;
    
    FLOWID fid;
    
    int main()
    {
          fid = indirizzi_ip;
    
          IDF idflow;
          
           if(idflow.insert(fid) == idflow.end(fid))
                  printf("L'indirizzo è nuovo ed è stato inserito nella lista.\n");
          else
                   printf("L'indirizzo è già presente nella lista.\n");
          
          exit(0)
    }
    Mi da diversi errori, ma sono sicuro che c'è qualcosa nelle dichiarazioni che sbaglio. Sapete darmi delle linee guida? Ho visto vari siti e vari esempi, e questo è il codice che ho tirato fuori.
    Grazie.

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Il tuo problema dipende da quanto riportato qui:
    http://www.eptacom.net/pubblicazioni/pub_it/nl_10.html
    sotto la voce Vincolare il tipo di stringa (più o meno a metà pagina appena sopra il codice).

    Per risolvere:
    codice:
    #include <set>
    #include <iostream>
    #include <string>
    #include <iterator>
    using namespace std;
    
    typedef set < string > IDF;
    
    FLOWID fid;
    
    int main()
    {
          fid = indirizzi_ip;
    
          IDF idflow;
          
           if(idflow.insert(fid) == idflow.end(fid))
                  printf("L'indirizzo è nuovo ed è stato inserito nella lista.\n");
          else
                   printf("L'indirizzo è già presente nella lista.\n");
          
          exit(0)
    }
    In ogni caso tieni presente (se non lo sai già) che il set ammette solo elementi univoci, pertanto l'if è puramente informativo
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  3. #3
    Utente di HTML.it
    Registrato dal
    Aug 2010
    Messaggi
    25
    Grazie shodan.
    Allora ho provato a leggere il link che hai postato, ma per ora ci ho capito poco, magari domani con la mente più lucida lo capirò meglio.
    Intanto ho provato la soluzione da te suggeritami, al posto di FLOWID ho messo string, e in effetti gli errori si sono ridotti:

    main.cpp: In function 'int main(int, char**)':
    main.cpp: 178: error: no matching function for call to 'std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::end(char [8])' /usr/lib/gcc/i686-pc-linux-gnu/4.4.4/include/g++-v4/bits/stl_set.h:300: note: candidates are: typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>:ther>::const_iterator std::set<_Key, _Compare, _Alloc>::end() const [with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >]
    make: *** [main.o] Error 1
    Alla riga 178 c'è l'if.
    Io ho messo l'if così perché a quanto mi risulta il find punta all'elemento, se lo trova, altrimenti punta ad un elemento successivo all'ultimo, che ovviamente non esiste, e quindi scrivendo in quel modo l'if, è come se scrivessi: "Se l'elemento non esiste fai questo, altrimenti fai quest'altro".
    Ho sbagliato anche quello?

    EDIT: mi accorgo ora che ho sbagliato una parte del codice, la riposto qui perché non posso editare il primo messaggio:

    codice:
    #include <set>
    #include <iostream>
    #include <string>
    #include <iterator>
    using namespace std;
    
    typedef char FLOWID 8
    
    typedef set < string > IDF;
    
    FLOWID fid;
    int main()
    {
           fid = indirizzi_ip;
           IDF idflow; 
           if(idflow.find(fid) == idflow.end(fid))
           {
                    printf("L'indirizzo è nuovo ed è stato inserito nella lista.\n");       
                    idflow.insert(fid);
           }
           else   
                     printf("L'indirizzo è già presente nella lista.\n");
           exit(0)
    }

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    In pratica non puoi usare dei char* come parametro di un template.

    idflow.end() non idflow.end(fid) [ mi era sfuggito prima ]
    FLOWID che è?

    L'if non è sbagliato se lo scopo è solo quello di informare. Ma come ho detto prima, se immetti nel set un elemento già presente, il set lo scarta da solo.
    Per dare un'idea, se immetti in un set un intero libro, il set conterrà solo le 26 lettere dell'alfabeto più la punteggiatura e qualche numero se presente; l'if è interno.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  5. #5
    Utente di HTML.it
    Registrato dal
    Aug 2010
    Messaggi
    25
    Originariamente inviato da shodan
    In pratica non puoi usare dei char* come parametro di un template.

    idflow.end() non idflow.end(fid) [ mi era sfuggito prima ]
    FLOWID che è?

    L'if non è sbagliato se lo scopo è solo quello di informare. Ma come ho detto prima, se immetti nel set un elemento già presente, il set lo scarta da solo.
    Per dare un'idea, se immetti in un set un intero libro, il set conterrà solo le 26 lettere dell'alfabeto più la punteggiatura e qualche numero se presente; l'if è interno.
    FLOWID devo essermelo perso nell'edit perché nel primo post l'avevo messo, mannaggia a me. Fixato comunque.
    Allora tolto fid dall'end e compila senza problemi. Solo che mi da l'if sempre vero.
    Ma tornando al tuo esempio del libro, io immetto una coppia di indirizzi, sorgente e destinazione, e se uno dei due cambia allora la coppia deve essere trattata come diversa, altrimenti, se un pacchetto con stessa sorgente e stesso destinatario, mi dice che è già presente.
    La differenza tra il mio caso e quello del libro è che nel mio caso io inserisco e confronto una stringa, mentre nel caso del libro inserisco i caratteri singolarmente, quindi se li trova li scarta e si ferma a 26 giusto?

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Si, perché 26 sono le lettere dell'alfabeto. ma non centra se inserisci una stringa o un carattere: l'algoritmo è lo stesso perché si parla di un generico elemento.
    Se inserisci "abracadabra" (in caratteri singoli) il set si comporta così:
    inserisce a, inserisce b, inserisce r, scarta a perché c'è già, inserisce c, scarta a perché c'è già, inserisce d, scarta a perché c'è già...

    Alla fine il set conterrà (in caratteri): abrcd

    Se inserisci "192.168.1.100", "192.168.1.200","10.0.0.1","192.168.1.100"; il set conterrà solo il primi tre dal momento che il quarto lo trova già, ragione per cui il tuo if è sempre vero.
    La cosa si applica anche alla map (che contiene coppie tipo: chiave - dato), tenendo presente che se durante l'inserimento viene rilevata una chiave doppia, la coppia viene scartata.
    Il succo del discorso è che sia set sia map garantiscono l'univocità dei dati inseriti.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  7. #7
    Comunque, dovendo fare un set di indirizzi IP io li memorizzerei come una struct, o un intero a 32 bit o una union dei due, non come una stringa... anche solo per il fatto che il confronto di stringhe non va bene per gli IP: 192.168.0.1 e 192.168.000.1 sono lo stesso IP ma facendo un confronto di stringhe risultano diversi.
    Amaro C++, il gusto pieno dell'undefined behavior.

  8. #8
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Senza contare che un confronto tra interi è molto più performante.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  9. #9
    Utente di HTML.it
    Registrato dal
    Feb 2009
    Messaggi
    131
    Originariamente inviato da MItaly
    Comunque, dovendo fare un set di indirizzi IP io li memorizzerei come una struct, o un intero a 32 bit o una union dei due, non come una stringa... anche solo per il fatto che il confronto di stringhe non va bene per gli IP: 192.168.0.1 e 192.168.000.1 sono lo stesso IP ma facendo un confronto di stringhe risultano diversi.
    Aggiungerei anche che con interi a 32 bit il confronto è molto più veloce e la lista occupa meno memoria.

  10. #10
    Utente di HTML.it
    Registrato dal
    Aug 2010
    Messaggi
    25
    Originariamente inviato da shodan
    Si, perché 26 sono le lettere dell'alfabeto. ma non centra se inserisci una stringa o un carattere: l'algoritmo è lo stesso perché si parla di un generico elemento.
    Se inserisci "abracadabra" (in caratteri singoli) il set si comporta così:
    inserisce a, inserisce b, inserisce r, scarta a perché c'è già, inserisce c, scarta a perché c'è già, inserisce d, scarta a perché c'è già...

    Alla fine il set conterrà (in caratteri): abrcd

    Se inserisci "192.168.1.100", "192.168.1.200","10.0.0.1","192.168.1.100"; il set conterrà solo il primi tre dal momento che il quarto lo trova già, ragione per cui il tuo if è sempre vero.
    La cosa si applica anche alla map (che contiene coppie tipo: chiave - dato), tenendo presente che se durante l'inserimento viene rilevata una chiave doppia, la coppia viene scartata.
    Il succo del discorso è che sia set sia map garantiscono l'univocità dei dati inseriti.
    E questo è male! Devo rivederlo. Ho provato anche con il size prima e dopo l'insert, e poi confrontando i due valori, ma ovviamente, come dici tu, la situazione non cambia.

    @MItaly: per brevità non ho postato come ho preso gli indirizzi, comunque la libreria pcap e li mappo in un array, tutto in automatico, quindi la formattazione è sempre la stessa (8 coppie di numeri esadecimali, 4 sorgente e 4 destinazione). Mi serve metterle così perché le uso per calcolarmi l'HMAC del pacchetto da usare come chiave per criptare lo stesso.
    La parte del sapere se il pacchetto appartiene ad un flusso noto o meno è perché ho bisogno di sapere se devo mandare dei dati o no.

    Cmq grazie a tutti. Ora cercherò di risolvere il problema di come fare a sapere se il dato era presente o è stato inserito.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.