IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Algorithme IRC


Sujet :

C

  1. #1
    Invité
    Invité(e)
    Par défaut Algorithme IRC
    Bonjour, je code un bot IRC, du coups j'ai besoin de créer un algorithme qui récupère le pseudo et le texte pour chaque méssage envoyé sur le canal IRC que mon bot gère.
    J'ai donc codé les fonctions suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    int gerer_recv(char* buff) {
    int i=1, limite = 0;
    char nick[50] = "";
    char *txt = NULL;
    txt = strstr(buff, "PRIVMSG");   
     
    if(txt == NULL) {                     // Si la chaine n'est pas un PRIVMSG on ne la traite pas
       printf("%s", buff);
       return 0;
    }
    while(buff[i] != '!' && i < 50) {  // La condition i<50 pour savoir si c'est un véritable 
    nick[i-1] = buff[i];                       // message a traiter car pseudo < 50 caractères de longs
    i++;
    }
    if(i==49)  {
    printf("%s", buff);                              
       return 0;
    }
    txt = strstr(txt, ":");
    printf("%s : %s", nick, txt+1); // On affiche la chaine située 1 caractère après le ':'
    }
     
    void* recv_line(void* data) {
    int i = 0, t_buff;
    char buff[512] = "";
    SOCKET serv = (SOCKET)data;
    t_buff = recv(serv, buff, 512, 0);
    gerer_recv(buff);
    }
    La fonction recv_line est dans un thread dans une boucle infinie dans mon main(), mais j'ai du mal avec mon algo car malgrès que je vérifie que les chaines traités contiennent des PRIVMSG, donc que au début de celle ci on a le pseudo de la source du méssage placé avant un '!' j'ai des chaines qui passent cette condition mais qui n'on pas de '!', d'ou ma condition i<50 sinon nick dépasse car la condition n'est jamais remplie.

    Et enfin, et surtout, mon programme fait chauffer mon ordi, je l'entend très vite, c'est le fait qu'il y ai un thread dans un while(1) ou car mon algo est mal fait ?

    Merci
    Dernière modification par Invité ; 01/05/2011 à 22h12.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Petit up, et GROS EDIT : maintenant mon soucis vien de l'algo en lui meme si quelqu'un avait une idée... Pour irc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <netdb.h>
    #include <sys/types.h>
        #include <sys/socket.h>
        #include <netinet/in.h>
        #include <arpa/inet.h>
        #include <unistd.h>
        #include <pthread.h>
     
        typedef int SOCKET;
        typedef struct sockaddr_in SOCKADDR_IN;
        typedef struct sockaddr SOCKADDR;
        #include "irc.h"
        #define INVALID_SOCKET -1
        #define SOCKET_ERROR -1
        #define closesocket(s) close(s)
        #define PORT 80
     
    int main(int argc, char *argv[])
    {
        struct timeval temps;
        temps.tv_sec = 0;
        temps.tv_usec = 100;
        int err;
        SOCKET serv = socket(AF_INET, SOCK_STREAM, 0);
        SOCKADDR_IN cserv;
        struct irc_msg ircmsg;
        ircmsg.serv = serv;
        ircmsg.nick = malloc(50 * sizeof(char));
        ircmsg.text = malloc(500 * sizeof(char));
        ircmsg.chaine = malloc(512 * sizeof(char));
        ircmsg.online = 0;
        pthread_t recevoir;
        struct hostent *adresse;
        fd_set read;
     
        if(argc == 1) {
                printf("Veuillez renseigner une adresse\n");
                    return 0;
        }
        adresse = gethostbyname(argv[1]);
        cserv.sin_addr = *((struct in_addr *)(adresse->h_addr));
        cserv.sin_family = AF_INET;
        cserv.sin_port = htons(6667);
        err = connect(serv, (SOCKADDR*)&cserv, sizeof(cserv));
     
        printf("Connexion a %s\n", inet_ntoa(cserv.sin_addr));
        if(err == -1) {
                printf("Err connection\n");
                    return 0;
        }
        printf("Connécté au serveur %s\n", argv[1]);
        send_line(serv, "NICK Bot-fox \r\n\r\n");
        send_line(serv, "PRIVMSG nickserv identify ganjaman\r\n\r\n");
        send_line(serv, "USER a a a a \r\n\r\n");      // A remplir correctement meme si le serveur s'en charge généralement
        send_line(serv, "JOIN #romfox\r\n\r\n");
     
        while(1) {
            pthread_create(&recevoir, NULL, recv_line, (void *)&ircmsg);
            FD_ZERO(&read);
            FD_SET(STDIN_FILENO, &read);
            select(STDIN_FILENO+1, &read,NULL,NULL,&temps);
            if(FD_ISSET(STDIN_FILENO, &read)) {
                    free(ircmsg.nick);
                        free(ircmsg.text);
                            free(ircmsg.chaine);
                                closesocket(serv);
                                return 0;
            }
            pthread_join(recevoir, NULL);
     
        }
        return 0;
     
     
    }
    irc.h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    struct irc_msg {
        SOCKET serv;
        char *nick;
        char *event;
        char *text;
        char *chaine;
        int online;
    };
     
    void send_line(SOCKET Client, char* buffer) {
        int i = 0;
     
        while(i< strlen(buffer)) {
               send(Client, (char *)&buffer[i], 1, 0);
               i++;
        }
    }
     
    int range(struct irc_msg *ircmsg) {
     
        char *txt = NULL;
        int i = 1;
        if(ircmsg->online == 0) {
            txt = strstr(ircmsg->chaine, "JOIN");
                if(txt != NULL) {
                        ircmsg->online = 1;
                                printf("NOW ONLINE %s\n", ircmsg->chaine);
                                        return 0;
                 }
     
        } // End if
            txt = strstr(ircmsg->chaine, "PRIVMSG");
                 if(txt != NULL) {
                     while(ircmsg->chaine[i] != '!') {
                         ircmsg->nick[i-1] = ircmsg->chaine[i];
     
                     }
                     txt = strstr(ircmsg->chaine+1, ":");
                          ircmsg->text = txt+1;
                               printf("%s : %s\n",ircmsg->nick,ircmsg->text);
     
                }  // End PRIVMSG
                printf("%s\n", ircmsg->chaine);
    }
     
    int fonctions(struct irc_msg *ircmsg) {
     
        return 0;
     
    }
     
    void* recv_line(void* data) {
        int i = 0, t_buff;
        struct irc_msg *irc_mss = (struct irc_msg *)data;
        t_buff = recv(irc_mss->serv, irc_mss->chaine, 512, 0);
        irc_mss->chaine[t_buff] = '\0';
        range(irc_mss);
    }
    Dernière modification par Invité ; 01/05/2011 à 21h42.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par romfox17 Voir le message
    Petit up, et GROS EDIT : maintenant mon soucis vien de l'algo en lui meme si quelqu'un avait une idée... Pour irc, en fait je recherche une idée pour bien traiter mes chaine recues.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <netdb.h>
    #include <sys/types.h>
        #include <sys/socket.h>
        #include <netinet/in.h>
        #include <arpa/inet.h>
        #include <unistd.h>
        #include <pthread.h>
     
        typedef int SOCKET;
        typedef struct sockaddr_in SOCKADDR_IN;
        typedef struct sockaddr SOCKADDR;
        #include "irc.h"
        #define INVALID_SOCKET -1
        #define SOCKET_ERROR -1
        #define closesocket(s) close(s)
        #define PORT 80
     
    int main(int argc, char *argv[])
    {
        struct timeval temps;
        temps.tv_sec = 0;
        temps.tv_usec = 100;
        int err;
        SOCKET serv = socket(AF_INET, SOCK_STREAM, 0);
        SOCKADDR_IN cserv;
        struct irc_msg ircmsg;
        ircmsg.serv = serv;
        ircmsg.nick = malloc(50 * sizeof(char));
        ircmsg.text = malloc(500 * sizeof(char));
        ircmsg.chaine = malloc(512 * sizeof(char));
        ircmsg.online = 0;
        pthread_t recevoir;
        struct hostent *adresse;
        fd_set read;
     
        if(argc == 1) {
                printf("Veuillez renseigner une adresse\n");
                    return 0;
        }
        adresse = gethostbyname(argv[1]);
        cserv.sin_addr = *((struct in_addr *)(adresse->h_addr));
        cserv.sin_family = AF_INET;
        cserv.sin_port = htons(6667);
        err = connect(serv, (SOCKADDR*)&cserv, sizeof(cserv));
     
        printf("Connexion a %s\n", inet_ntoa(cserv.sin_addr));
        if(err == -1) {
                printf("Err connection\n");
                    return 0;
        }
        printf("Connécté au serveur %s\n", argv[1]);
        send_line(serv, "NICK Bot-fox \r\n\r\n");
        send_line(serv, "PRIVMSG nickserv identify motdepasse\r\n\r\n");
        send_line(serv, "USER a a a a \r\n\r\n");      // A remplir correctement meme si le serveur s'en charge généralement
        send_line(serv, "JOIN #romfox\r\n\r\n");
     
        while(1) {
            pthread_create(&recevoir, NULL, recv_line, (void *)&ircmsg);
            FD_ZERO(&read);
            FD_SET(STDIN_FILENO, &read);
            select(STDIN_FILENO+1, &read,NULL,NULL,&temps);
            if(FD_ISSET(STDIN_FILENO, &read)) {
                    free(ircmsg.nick);
                        free(ircmsg.text);
                            free(ircmsg.chaine);
                                closesocket(serv);
                                return 0;
            }
            pthread_join(recevoir, NULL);
     
        }
        return 0;
     
     
    }
    irc.h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    struct irc_msg {
        SOCKET serv;
        char *nick;
        char *event;
        char *text;
        char *chaine;
        int online;
    };
     
    void send_line(SOCKET Client, char* buffer) {
        int i = 0;
     
        while(i< strlen(buffer)) {
               send(Client, (char *)&buffer[i], 1, 0);
               i++;
        }
    }
     
    int range(struct irc_msg *ircmsg) {
     
        char *txt = NULL;
        int i = 1;
        if(ircmsg->online == 0) {
            txt = strstr(ircmsg->chaine, "JOIN");
                if(txt != NULL) {
                        ircmsg->online = 1;
                                printf("NOW ONLINE %s\n", ircmsg->chaine);
                                        return 0;
                 }
     
        } // End if
            txt = strstr(ircmsg->chaine, "PRIVMSG");
                 if(txt != NULL) {
                     while(ircmsg->chaine[i] != '!') {
                         ircmsg->nick[i-1] = ircmsg->chaine[i];
     
                     }
                     txt = strstr(ircmsg->chaine+1, ":");
                          ircmsg->text = txt+1;
                               printf("%s : %s\n",ircmsg->nick,ircmsg->text);
     
                }  // End PRIVMSG
                printf("%s\n", ircmsg->chaine);
    }
     
    int fonctions(struct irc_msg *ircmsg) {
     
        return 0;
     
    }
     
    void* recv_line(void* data) {
        int i = 0, t_buff;
        struct irc_msg *irc_mss = (struct irc_msg *)data;
        t_buff = recv(irc_mss->serv, irc_mss->chaine, 512, 0);
        irc_mss->chaine[t_buff] = '\0';
        range(irc_mss);
    }
    Dernière modification par Invité ; 01/05/2011 à 23h12.

  4. #4
    Membre éclairé
    Avatar de Elijha
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Avril 2003
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Points : 742
    Points
    742
    Par défaut
    Bonsoir,

    Peut-être trouveras tu un compléments d'informations ici.
    - Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !
    - Travailler dur n'a jamais tué personne, mais pourquoi prendre le risque (Edgar Bergen)

  5. #5
    Invité
    Invité(e)
    Par défaut
    En fait je parlais pas du programme, comme tu vois j'utilise déja les sockets, mais plutot de l'algo a utiliser pour traiter les chaines ?

  6. #6
    Invité
    Invité(e)
    Par défaut
    J'ai un code minimum sans algorithme, c'est plus lisible et si quelqu'un pouvait me donner des idées pour extraire le pseudo et le texte déja, vu la syntaxe de IRC.

    main.c :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <netdb.h>
    #include <sys/types.h>
        #include <sys/socket.h>
        #include <netinet/in.h>
        #include <arpa/inet.h>
        #include <unistd.h>
        #include <pthread.h>
     
        typedef int SOCKET;
        typedef struct sockaddr_in SOCKADDR_IN;
        typedef struct sockaddr SOCKADDR;
        #include "irc.h"
        #define INVALID_SOCKET -1
        #define SOCKET_ERROR -1
        #define closesocket(s) close(s)
        #define PORT 80
     
    int main(int argc, char *argv[])
    {
        struct timeval temps;
        temps.tv_sec = 0;
        temps.tv_usec = 100;
        int err;
        SOCKET serv = socket(AF_INET, SOCK_STREAM, 0);
        SOCKADDR_IN cserv;
        struct irc_msg ircmsg;
        ircmsg.serv = serv;
        ircmsg.nick = malloc(50 * sizeof(char));
        ircmsg.text = malloc(500 * sizeof(char));
        ircmsg.chaine = malloc(512 * sizeof(char));
        ircmsg.online = 0;
        pthread_t recevoir;
        struct hostent *adresse;
        fd_set read;
     
        if(argc == 1) {
                printf("Veuillez renseigner une adresse\n");
                    free(ircmsg.nick);
                        free(ircmsg.text);
                            free(ircmsg.chaine);
                    return 0;
        }
        adresse = gethostbyname(argv[1]);
        cserv.sin_addr = *((struct in_addr *)(adresse->h_addr));
        cserv.sin_family = AF_INET;
        cserv.sin_port = htons(6667);
        err = connect(serv, (SOCKADDR*)&cserv, sizeof(cserv));
     
        printf("Connexion a %s\n", inet_ntoa(cserv.sin_addr));
        if(err == -1) {
                printf("Err connection\n");
                    return 0;
        }
        printf("Connécté au serveur %s\n", argv[1]);
        send_line(serv, "NICK Bot-fox \r\n\r\n");
        send_line(serv, "PRIVMSG nickserv identify motdepasse\r\n\r\n");
        send_line(serv, "USER a a a a \r\n\r\n");      // A remplir correctement meme si le serveur s'en charge généralement
        send_line(serv, "JOIN #romfox\r\n\r\n");
     
        while(1) {
            pthread_create(&recevoir, NULL, recv_line, (void *)&ircmsg);
            FD_ZERO(&read);
            FD_SET(STDIN_FILENO, &read);
            select(STDIN_FILENO+1, &read,NULL,NULL,&temps);
            if(FD_ISSET(STDIN_FILENO, &read)) {
                    free(ircmsg.nick);
                        free(ircmsg.text);
                            free(ircmsg.chaine);
                                closesocket(serv);
                                return 0;
            }
            pthread_join(recevoir, NULL);
     
        }
        return 0;
    }
    irc.h :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    struct irc_msg {
        SOCKET serv;
        char *nick;
        char *event;
        char *text;
        char *chaine;
        int online;
    };
     
    void send_line(SOCKET Client, char* buffer) {
        int i = 0;
     
        while(i< strlen(buffer)) {
               send(Client, (char *)&buffer[i], 1, 0);
               i++;
        }
    }
     
    int range(struct irc_msg *ircmsg) {
     
     
        printf("%s\n", ircmsg->chaine);
    }
     
    int fonctions(struct irc_msg *ircmsg) {
        char *txt = NULL;
        int t_buff = strlen(ircmsg->chaine);
     
        txt = strstr(ircmsg->chaine, "PING");
        if (txt != NULL && ircmsg->chaine[0] == 'P') {
        ircmsg->chaine[1] = 'O';
        printf("%s", ircmsg->chaine);
        send_line(ircmsg->serv, ircmsg->chaine);
        send_line(ircmsg->serv, "\r\n\r\n");
        return 0;
        }
     
     
        return 0;
     
    }
     
    void* recv_line(void* data) {
        int i = 0, t_buff;
        struct timeval temps;
        temps.tv_sec = 0;
        temps.tv_usec = 100;
        fd_set read;
        struct irc_msg *irc_mss = (struct irc_msg *)data;
        FD_ZERO(&read);
        FD_SET(irc_mss->serv, &read);
        select(irc_mss->serv+1, &read, NULL, NULL, &temps);
        if(FD_ISSET(irc_mss->serv, &read)) {
        t_buff = recv(irc_mss->serv, irc_mss->chaine, 512, 0);
        irc_mss->chaine[t_buff] = '\0';
        range(irc_mss);
        fonctions(irc_mss);
        }
    }
    Dernière modification par Invité ; 02/05/2011 à 20h10.

  7. #7
    Membre éclairé
    Avatar de Elijha
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Avril 2003
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Points : 742
    Points
    742
    Par défaut
    Bonjour,

    J'ai pas bien compris ta question, mais si tu cherches à extraire le pseudo et la chaîne, il suffit de "taper" dans les champs de ta structure de données, comme tu l'as fait pour chaine ou serv.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    struct irc_msg {
        SOCKET serv;
        char *nick;
        char *event;
        char *text;
        char *chaine;
        int online;
    };
     
    // Dans la fonction recv_line(...) par exemple
    printf("Pseudo : %s\n", ircmsg->nick) ;
    printf("Texte  : %s\n", ircmsg->text) ;
    - Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !
    - Travailler dur n'a jamais tué personne, mais pourquoi prendre le risque (Edgar Bergen)

  8. #8
    Invité
    Invité(e)
    Par défaut
    Salut, plutot avec sprintf que printf je suppose :p Heu ba en fait je sais faire sa mais je dois les extraires de méssages qui ont plusieurs formats.

    EDIT : J'ai aussi rajouté les frees au cas ou on quitte directement le programme car le host n'a pas été donné.

    re-EDIT : Je rajoute la syntaxe IRC pour ceux qui ne la connaissent pas qui voudraient m'aider.

    Les serveurs et les clients IRC génèrent chacun des messages pouvant ou non générer une réponse. Ces messages ont toujours le même format (les crochets indiquent une partie optionnelle dans le message).

    [{:}{prefix}{SP}]{COMMANDE}[{SP}{PARAMETRES}]{CRLF}

    Le séparateur SP est un espace (code ascii : 0x20). Le séparateur CRLF est le duo "Retour Chariot, Fin de Ligne" (codes ascii 0x0D et 0x0A).
    À noter que les caractères CR (0x0D), LF (0x0A) et NUL (0x00) sont interdits dans les messages IRC. De plus, la longueur d'un message IRC est de 512 caractères au maximum, y compris le CRLF final.
    Le préfix n'est utilisé que pour un message provenant d'un serveur, il doit être ignoré s'il provient d'un client. Si le message est destiné à un serveur ou que le message a été émis sur le réseau par un serveur, le préfixe est simplement le nick du client, ou le nom du serveur ayant envoyé le message sur le réseau. Si le message est destiné à un client et que c'est un client qui a envoyé le message sur le réseau, alors le préfix suit cette syntaxe :

    {NICK}{!}{NOM DU CLIENT}{@}{DOMAINE DU CLIENT}

    La commande est soit un mot (une suite de une ou plusieurs lettres (A-Z) insensibles à la casse), soit un code de trois chiffres. Les codes de trois chiffres correspondent à des réponses de serveur, chacun ayant un nom, pour chaque commande, les réponses possibles seront listées. Les paramètres sont des chaînes de caractères sans espace, séparées par des espaces. À noter que le dernier paramètre peut contenir des espaces, dans ce cas, son premier caractère doit alors être les deux-points (. Chaque commande a ses paramètres.

  9. #9
    Membre éclairé
    Avatar de Elijha
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Avril 2003
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Points : 742
    Points
    742
    Par défaut
    Bonjour,

    Ok ! On avance avec un peu plus d'informations
    Peut-être qu'avec la fonction sscanf ferait l'affaire. Regarde le man scanf.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    char prefix[128] = "" ;
    char commande[128] = "" ;
    char parametres[128] = "" ;
     
    // Si message en provenance d'un serveur
    ret = sscanf(buffer, "[ %s ]%s[ %s ]\x0D\x0A", prefix, commande, parametres) ;
    if(ret==3) {
        printf("Prefix : %s\n", prefix) ;
        printf("Commande : %s\n", commande) ;
        printf("Paramètres : %s\n", parametres) ;
    }
    Cela devrait fonctionner si tous les données sont présentes (préfixe/commande/paramètres). Comme elles peuvent être optionnelles, il faut vérifier le retour de sscanf (1, 2 ou 3 éléments lus), ou bien analyser champs par champs ("[ %s ]", "%s" et "[ %s ]\x0D\x0A").

    Bonne continuation.
    - Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !
    - Travailler dur n'a jamais tué personne, mais pourquoi prendre le risque (Edgar Bergen)

  10. #10
    Invité
    Invité(e)
    Par défaut
    Salut, je ne connaissais pas sscanf, je vais la dompter Mais je ne suis pas sur que cela marche car les crochets de l'exemple ne sont pas dans les méssages, regarde un exemple de méssage qui transite en provenance d'un client vers le canal irc :

    :rom_!~rom@n0017-1-88-176-116-84.fbx.proxad.net PRIVMSG #romfox :salut
    Du coups je pense plutot que la solution serait de récupérer le pseuso entre le 1er ':' et le '!', puis de rechercher soit un 'NOTICE' soit un 'PRIVMS', puis d'aller chercher le texte apres le deuxième ':', tout sa a coups de strstr je pense, c'est comme ça que j'avais commencer mais j'éspérais que quelqu'un ai une meilleur solution Pour récupérer le host, le domain, etc, je ferais sa plus tard pour l'instant mon bot doit déja traiter le texte :p

    Merci de ton aide, je reste a l'écoute de propositions.

    Edit : en fait merci pour sscanf, je viens de comprendre que l'éspace entre les arguments devrai suffir pour isoler les chaines

  11. #11
    Membre éclairé
    Avatar de Elijha
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Avril 2003
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Points : 742
    Points
    742
    Par défaut
    Bonsoir,

    Citation Envoyé par romfox17
    Salut, pourrait tu m'expliquer pourquoi tu mets des crochets dans le sscanf et comment se servir de cette fonction dans mon cas car j'obtiens une erreur de segmentation.
    Ne connaissant pas le format d'une trame IRC, j'étais persuadé qu'il y avait les crochets ouvrant et fermant. Le segment fault est normal, car les crochets font partis du format du sscanf (voir le man).

    Pour la liste des commandes IRC, voici un lien très documenté : RCF1459.

    Sinon voici un test (non exhaustif je te l'accorde) d'une analyse d'une commande. J'ai bidouiller ça sur un coin de mon bureau
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int main(int argc, char *argv[])
    {   
        char *strIrc = ":rom!~rom@n0017-1-88-176-116-84.fbx.proxad.net PRIVMSG rom :salut. comment vas tu ?\n" ;
        // char *strIrc = ":rom_!~rom@n0017-1-88-176-116-84.fbx.proxad.net PRIVMSG #romfox :salut. comment vas tu ?\n" ;
        // char *strIrc = ":rom!~rom@n0017-1-88-176-116-84.fbx.proxad.net PRIVMSG +%@#romfox :salut. comment vas tu ?\n" ;
        // char *strIrc = ":rom!~rom@n0017-1-88-176-116-84.fbx.proxad.net PRIVMSG $*.mynet.net :salut. comment vas tu ?\n" ;
     
        int ret = 0 ;
     
        char nickName[128] = "" ;
        char name[128] = "" ;
        char domaine[128] = "" ;
        char commande[128] = "" ;
        char parametres[128] = "" ;
     
        char texte[128] = "" ;
     
        // [{:}{prefix}{SP}]{COMMANDE}[{SP}{PARAMETRES}]{CRLF}
        // {prefix} = {NICK}{!}{NOM DU CLIENT}{@}{DOMAINE DU CLIENT}
        // {:}{{NICK}{!}{NOM DU CLIENT}{@}{DOMAINE DU CLIENT}}{SP}]{COMMANDE}[{SP}{PARAMETRES}]{CRLF}
     
        ret = sscanf(strIrc, ":%[^!]!%[^@]@%s %s %[^\n]", nickName, name, domaine, commande, parametres) ;
        if(ret==5) {
            printf("{NICK}              : %s\n", nickName) ;
            printf("{NOM DU CLIENT}     : %s\n", name) ;
            printf("{DOMAINE DU CLIENT} : %s\n", domaine) ;
            printf("{COMMANDE}          : %s(%s)\n", commande, parametres) ;
     
            // Analyse des commandes et de leurs paramètres
            if(!strcmp(commande, "PRIVMSG")) {
                /* 
                   Il peu avoir 4 formats différent de la commande PRIVMSG
                    - 1. PRIVMSG <nick> :<text>                 Send a private message
                    - 2. PRIVMSG <#channel> :<text>             Send a message to a channel
                    - 3. PRIVMSG <prefix><#channel> :<text>     Send a message to users with <prefix> in <#channel> only
                    - 4. PRIVMSG $<mask> :<text>                Send a message to all users on servers matching <mask>
                 */
                // Cas n°4
                if(strstr(parametres, "$")==parametres) {
                    char mask[128] = "" ;
                    ret = sscanf(parametres, "$%s :%[^\n]\n", mask, texte) ;
                    printf("Cas n°4 ret = %d\n", ret) ;
                    if(ret==2) {
                        printf("mask  : %s\n", mask) ;
                        printf("texte : %s\n", texte) ;
                    }
                }
                // Cas n°2 ou n°3
                else if(strstr(parametres, "#")) {
                    char channel[128] = "" ;
                    // Cas n°2
                    if(parametres[0]=='#') {
                        ret = sscanf(parametres, "#%s :%[^\n]\n", channel, texte) ;
                        printf("Cas n°2 ret = %d\n", ret) ;
                        if(ret==2) {
                            printf("channel : %s\n", channel) ;
                            printf("texte   : %s\n", texte) ;
                        }
                    }
                    // Cas n°3
                    else {
                        char prefix[128] = "" ;
                        ret = sscanf(parametres, "%[^#]#%s :%[^\n]\n", prefix, channel, texte) ;
                        printf("Cas n°3 ret = %d\n", ret) ;
                        if(ret==3) {
                            printf("prefix  : %s\n", prefix) ;
                            printf("channel : %s\n", channel) ;
                            printf("texte   : %s\n", texte) ;
                        }
                    }
                }
                // Cas n°1
                else {
                    char nick[128] = "" ;
                    ret = sscanf(parametres, "%s :%[^\n]\n", nick, texte) ;
                    printf("Cas n°1 ret = %d\n", ret) ;
                    if(ret==2) {
                        printf("nick  : %s\n", nick) ;
                        printf("texte : %s\n", texte) ;
                    }
                }
            }
        }
     
        return EXIT_SUCCESS ;
    }
    En gros, il y a une première analyse du message. Une fois la commande et ses paramètres extraient, il y a une seconde analyse, celle des paramètres de la commande.
    Les différents formats du scanf utilisés sont :
    • "%s" : Copie tous les caractères jusqu'à trouvé un espace (sans l'inclure).

    • ":%[^!]!" : Copie tous les caractères entre ':' et '!' sans les inclures.

    • "%[^\n]" : Copie tous les caractères jusqu'au retour chariot en l'incluant.

    Après, je pense que tu comprendras le principe.

    A voir l'utilisation de flex et bison (il faudra t'adresser à quelqu'un d'autre car je ne maitrise pas).
    - Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !
    - Travailler dur n'a jamais tué personne, mais pourquoi prendre le risque (Edgar Bergen)

  12. #12
    Invité
    Invité(e)
    Par défaut
    Waw ! Tu me réponds totalement Merci beaucoups

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Formalisation graphique des algorithmes
    Par David R. dans le forum Algorithmes et structures de données
    Réponses: 14
    Dernier message: 08/12/2012, 10h21
  2. Algorithme de randomisation ... ( Hasard ...? )
    Par Anonymous dans le forum Assembleur
    Réponses: 8
    Dernier message: 06/09/2002, 14h25
  3. recherches des cours ou des explications sur les algorithmes
    Par Marcus2211 dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 19/05/2002, 22h18
  4. Recherche de documentation complète en algorithmes
    Par Anonymous dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 29/03/2002, 12h09
  5. Algorithme génétique
    Par Stephane.P_(dis Postef) dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 15/03/2002, 17h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo