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 :

aide Segfault minishell


Sujet :

C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Novembre 2011
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Novembre 2011
    Messages : 95
    Points : 34
    Points
    34
    Par défaut aide Segfault minishell
    Bonjour,
    j'ai un petit problème mon minishell segfault et je ne comprends pas pourquoi. Je l'ai lancé sous valgrind et il me donne
    Process terminating with default action of signal 11 (SIGSEGV)
    ==15010== Access not within mapped region at address 0x8
    ==15010== at 0x401FD3: prompt (cmd.c:175)
    ==15010== by 0x401255: main (main.c:51)
    ==15010== If you believe this happened as a result of a stack
    ==15010== overflow in your program's main thread (unlikely but
    ==15010== possible), you can try to increase the size of the
    ==15010== main thread stack using the --main-stacksize= flag.
    ==15010== The main thread stack size used in this run was 8388608.
    voici le code
    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
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    char     *launch_current(char *current, char **env)
    {
      {
        char  *pwd; // char* qui va contenir le chemin du dossier courant
        char  *tmp; // char* temporaire
        char  *tmp1; //char* temporaire
        int   i;
     
        i = 0;
        if (current == NULL)
          my_putstr_error("erreur current is NULL.\n");
        else
          {
            tmp = malloc(my_strlen(current) * sizeof(*tmp));
            tmp1 = malloc(my_strlen(current) * sizeof(*tmp1));
            pwd = malloc(500 * sizeof(char));
            if (tmp == NULL || tmp1 == NULL || pwd == NULL)
              my_putstr_error("Error malloc tmp, tmp1 or pwd is NULL.\n");
            else
              {
                pwd = *my_getenv("PWD", env); // my_getenv("PWD",env) retourne le chemin du dossier actuel
                my_strcpy(tmp, pwd); // copie la valeur de pwd dans tmp
                while (i < 4)
                  i++;
                i = 0;
                while (tmp[i] != '\0')
                  {
                    // je supprime PWD= 
                    if (tmp[i] == 'P' && tmp[i + 1] =='W' && tmp[i + 2] == 'D')
                      {
                        tmp[i] = '\n';
                        tmp[i + 1] = '\n';
                        tmp[i + 2] = '\n';
                        tmp[i + 3] = '\n';
                      }
                    i++;
                  }
                del_char(tmp, '\n'); //je supprime les \n que j'ai inséré plus haut
                strcat(tmp, "/"); // j'ajoute un / dans tmp  
                strcat(tmp, current); // j'ajoute la valeur de current dans tmp
              }
          }
        return (tmp);
      }
    }
     
     
     
    int    prompt(t_env *env2, t_list *env)
    { 
      char  *cd; //pour la commande cd
      char  *cd1; 
      char  *tmp; //variable temporaire
      int   erno; //stocke la valeur de retour de execute1
      char  *error; // contiens le nom de la comme qui a echoué.
      char  *tmp1;
     
      error = 0;
      erno = 0;
      if (env2->buffer == NULL)
        my_putstr_error("errreur malloc");
      my_putstr("$-->");
      memset(&env2->buffer[0], 0, 4096);
      if (read(0, env2->buffer, 4095) == 0)
        {
          my_putchar('\n');
          return (0);
        }
      else
        {
          cd = malloc(my_strlen(env2->buffer) * sizeof(char));
          cd1 = malloc(my_strlen(env2->buffer) * sizeof(char));
          tmp = malloc(my_strlen(env2->buffer) * sizeof(char));
          tmp1 = malloc(my_strlen(env2->buffer) * sizeof(char));
          error = malloc(my_strlen(env2->buffer) * sizeof(char));
          if (cd == NULL || tmp1 == NULL || error == NULL || cd1 == NULL || tmp == NULL)
            my_putstr_error("error\n");
          else
            {
              if (my_strcmp(env2->buffer, "exit\n") == 0)
                return (0);
              else
                {
                  if (env2->buffer[0] == '.' && env2->buffer[1] =='/')
                    {
                      my_strncpy(tmp, env2->buffer, 2); // je copie les 2 premiers caractères de env2->buffer et les stockes dans tmp
                      printf("tmp%s\n", tmp);
                      del_str(env2->buffer, tmp);
                      printf("env2->buffer %s\n", env2->buffer);
                      if (env2->buffer == NULL)
                        my_putstr_error("error env2->buffer is NULL");
                      /* else */
                      /*   { */
                      my_strcpy(error, env2->buffer);
      env2->buffer = launch_current(
    env2->buffer,
    env->environ);
                      erno = execute1(env2, env, error);
                      if (erno == 65280)
                        {
                          if (env2->buffer[my_strlen(env2->buffer) - 1] == '\n')
                            env2->buffer[my_strlen(env2->buffer) - 1] = 0;
                        }
                    }
                  my_strncpy(cd,env2->buffer,2);
                  my_strcpy(cd1, env2->buffer);
                  del_str(cd1, cd);
                  strcpy(tmp, cd1);
                  if (strncmp(cd, "cd\n", 2) == 0)
                    my_cd(tmp);
                  else if (my_strncmp(env2->buffer, "setenv\n", 5) == 0)
                    {
                      env = add_firsttab(env, env2->environ);
                      setenv(env, env2->buffer);
                        }
                      else
                        loop(env2);
                }
            }
        }
      /* } */
      return (42);
    }
    merci et bonne journée

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Code extrêmement confus et non-commenté, noms de variables non-explicites, aucune explication sur le fait d'allouer cinq buffers de la même taille que la chaîne saisie (possiblement sans caractère nul)...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Novembre 2011
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Novembre 2011
    Messages : 95
    Points : 34
    Points
    34
    Par défaut
    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
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
     
    /*                                                                                                                                                                                            
    ** cmd.c for minishell in /home/boivin_r/rendu/PSU_2014_minishell1                                                                                                                            
    **                                                                                                                                                                                            
    ** Made by Rémi boivin                                                                                                                                                                        
    ** Login   <boivin_r@epitech.net>                                                                                                                                                             
    **                                                                                                                                                                                            
    ** Started on  Tue Jan 20 13:42:36 2015 Rémi boivin                                                                                                                                           
    ** Last update Sat Jan 31 17:28:33 2015 Rémi boivin                                                                                                                                           
    */
     
    #include "my.h"
     
    int     check_command(char **tab1, t_env *env2)
    {
      int   erno;
     
      erno = 0;
      my_strcpy(env2->commande, tab1[0]);
      del_str(env2->commande, "PATH");
      del_char(env2->commande, '='); // supprime le charatère '='
      strcat(env2->commande, "/");
      strcat(env2->commande, env2->buffer);
      env2->commande[my_strlen(env2->commande) - 1] = '\0';
      erno = execute(env2); // exécute la commende contenu dans env2->commande
      return (erno);
    int     check_command1(char **tab1, t_env *env2)
    {
      int   j;
      int   erno;
     
      erno = 65280;
      j = 0;
      while (erno != 0)
        {
          if (j >= 5)
            {
              my_putstr_error("Commande introuvable.\n");
              return (-1);
            }
          else
            {
              my_strcpy(env2->commande, tab1[j]);
              del_char(env2->commande, '=');
              del_str(env2->commande, "PATH");
              strcat(env2->commande, "/");
              strcat(env2->commande, env2->buffer);
              env2->commande[my_strlen(env2->commande) - 1] = '\0';
              erno = execute(env2);
            }
          j++;
        }
      return (0);
    }
    char     *launch_current(char *current, char **env)
    {
        char  *pwd;
        char  *tmp;
        char  *tmp1;
        int   i;
     
        i = 0;
        if (current == NULL)
          my_putstr_error("erreur current is NULL.\n");
        else
          {
            tmp = malloc(my_strlen(current) * sizeof(*tmp));
            tmp1 = malloc(my_strlen(current) * sizeof(*tmp1));
            pwd = malloc(500 * sizeof(char));
            if (tmp == NULL || tmp1 == NULL || pwd == NULL)
              my_putstr_error("Error malloc tmp, tmp1 or pwd is NULL.\n");
            else
              {
                pwd = *my_getenv("PWD", env);// stocke la valeur env de PWD
                my_strcpy(tmp, pwd);
                while (i < 4)
                  i++;
                i = 0;
                while (tmp[i] != '\0')
                  {
                    if (tmp[i] == 'P' && tmp[i + 1] =='W' && tmp[i + 2] == 'D')
                      {
                        tmp[i] = '\n';
                        tmp[i + 1] = '\n';
                        tmp[i + 2] = '\n';
                        tmp[i + 3] = '\n';
                      }
                    i++;
                  }
                del_char(tmp, '\n');
                strcat(tmp, "/");
                strcat(tmp, current);
              }
          }
        return (tmp);
     }
     
    }
    int    loop(t_env *env2)
    {
      char  **tab1;
      int   i;
      int   erno;
     
      erno = 0;
      i = 0;
      tab1 = init(env2);
      if (env2->buffer == NULL)
        my_putstr_error("error malloc\n");
      while (tab1[i] != NULL)
        {
          env2->commande = malloc((my_strlen(tab1[i] + 1) + my_strlen(env2->buffer) + 1) * sizeof(char));
          i++;
        }
      if (env2->commande == NULL)
        my_putstr_error("errreur amlloc");
      erno = check_command(tab1, env2); // on esssaye d'executer la commande et si erno == 65280
      if (erno == 65280)
        check_command1(tab1, env2); // on execute jusqu'a ce que la commande s'exécute ou que i est == 7
      return (0);
    }
     
    int     parse1(t_env *env2, t_list *env, char *error)
    {
       if (my_strcmp(env2->buffer, "exit\n") == 0)
        return (0);
      else
        {
          if (env2->buffer[0] == '.' && env2->buffer[1] =='/')
            {
              del_str(env2->buffer, "./");
              if (env2->buffer == NULL)
                my_putstr_error("[CMD] Error: env2->buffer is NULL.\n");
              else
                execute1(env2, env, error);
            }
          else if (my_strncmp(env2->buffer, "cd", 1) == 0)
            my_cd(env2);
          else if (my_strncmp(env2->buffer, "setenv\n", 5) == 0)
            setenv(env, env2);
          else
            loop(env2);
        }
      return (2);
    }
    int    prompt(t_env *env2, t_list *env)
    {
      char  *error;
     
      if (env2->buffer == NULL)
        my_putstr_error("[CMD] Errreur malloc: env2->buffer is NULL.\n");
      else
        {
          my_putstr("$-->");
          memset(&env2->buffer[0], 0, 4096);
          if (read(0, env2->buffer, 4095) == 0)
            {
              my_putchar('\n');
              return (0);
            }
          else
            {
              error = malloc(my_strlen(env2->buffer) * sizeof(char));
              if (error == NULL)
                my_putstr_error("[CMD] Error malloc: char* error.\n");
              else
                parse1(env2, env, error);
            }
        }
      return (42);
    }

  4. #4
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    J'ai mis en commentaires (//) les lignes non indispensables à la compréhension de ce que fait le programme (mais ne sont pas à supprimer pour autant) et mes remarques en commentaires (/* */)
    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
    char     *launch_current(char *current, char **env)
    {
     /* { */
    /****** faire des blocs inutiles alourdit inutilement la lecture ******/
        char  *pwd; // char* qui va contenir le chemin du dossier courant
        char  *tmp; // char* temporaire
     /*   char  *tmp1; //char* temporaire */
    /****** tmp1 ne sert à rien ******/
        int   i;
     
        i = 0;
        //if (current == NULL)
        //  my_putstr_error("erreur current is NULL.\n");
        //else
        //  {
            tmp = malloc(my_strlen(current) * sizeof(*tmp));
        /*    tmp1 = malloc(my_strlen(current) * sizeof(*tmp1)); */
            pwd = malloc(500 * sizeof(char));
        //    if (tmp == NULL || tmp1 == NULL || pwd == NULL)
        //      my_putstr_error("Error malloc tmp, tmp1 or pwd is NULL.\n");
        //    else
        //      {
                pwd = *my_getenv("PWD", env); // my_getenv("PWD",env) retourne le chemin du dossier actuel
    /****** Ceci détruit l'adresse de la zone allouée ligne 18 -> fuite mémoire******/
                my_strcpy(tmp, pwd); // copie la valeur de pwd dans tmp
    /****** Qu'est-ce qui garantit qu'il y a assez de place pour cette copie ?******/
        /*        while (i < 4) */
        /*          i++;   */
    /****** A quoi servent ces 2 lignes 27,28 de code ******/
                i = 0;
                while (tmp[i] != '\0')
                  {
                    // je supprime PWD= 
                    if (tmp[i] == 'P' && tmp[i + 1] =='W' && tmp[i + 2] == 'D')
    /****** Sortie potentielle du buffer tmp ligne 34 : qui garantit que l'élément en i+2 est dans le buffer tmp ******/
                      {
                        tmp[i] = '\n';
                        tmp[i + 1] = '\n';
                        tmp[i + 2] = '\n';
                        tmp[i + 3] = '\n';
    /******  Qui garantit qu'on n'écrase pas en i+3 le caractère '\0'  dans le buffer tmp  ? ******/
                      }
                    i++;
                  }
                del_char(tmp, '\n'); //je supprime les \n que j'ai inséré plus haut
    /****** ???? ******/
                strcat(tmp, "/"); // j'ajoute un / dans tmp  
                strcat(tmp, current); // j'ajoute la valeur de current dans tmp
    /****** Il est CERTAIN qu'ici on sort du buffer tmp alloué ligne 16 ******/
        //      }
        //  }
        return (tmp);
    /*  } */
    }
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Novembre 2011
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Novembre 2011
    Messages : 95
    Points : 34
    Points
    34
    Par défaut
    voici le code source du projets avec les modifications qu'on m'a dis (de ce que j'en ai compris)
    minishell1.zip
    mais j'ai un
    Error in `./mysh': malloc(): memory corruption: 0x00000000010e23f0 ***
    ça veux dire quoi ?

  6. #6
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    Tu te moques de nous là, non ? En gros tu fais toujours n'importe quoi avec la mémoire. valgrind te donne même la ligne à laquelle ça arrive ! Après il te suffit de refaire la logique de ton programme en sens inverse pour tenter de comprendre d'où ça vient.

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Ça veut dire que malloc() vient de détecter qu'il s'est passé quelque chose de mal à un moment donné sur le tas.

    Par exemple, un débordement de buffer alloué.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Novembre 2011
    Messages
    95
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Novembre 2011
    Messages : 95
    Points : 34
    Points
    34
    Par défaut
    non j'ai mal compris ce que diogene à dit.
    ok merci. Je vais voir.

  9. #9
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Points : 465
    Points
    465
    Par défaut
    ce que @Médinoc a très bien expliqué
    Ça veut dire que malloc() vient de détecter qu'il s'est passé quelque chose de mal à un moment donné sur le tas.

    Par exemple, un débordement de buffer alloué.
    si ton malloc te donne ça c'est pas très compliqué tu lui donne un nombre incorrect car son prototype est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void* malloc (size_t size);
    où size_t est un chiffre
    je pense que ton my_strlen doit bugger et lui retourné -1 et allouer -1 octet à pars permalien je vois pas qui peut le faire
    ou alors tu passe une chaine sans \0 à ton strlen qui déborde et finis en buffer overflow( essayer de lire ou écrire dans une adresse mémoire qui n’appartient pas à ton programme)
    comme la montré @Diogène tu déborde de ton buffer tmp avec tes strcat

    sans être méchant comprend tu ce qu'il se passe en mémoire aux niveau de tmp lorsque tu fait strcat?

    juste pour t'aider à comprendre
    je te donne un code exemple pour t'aider
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    char *tmp=malloc(50);//j'alloue 50octet as tmp
    for(i=0;i<49;i++)
    {
        tmp[i]=a;
    }
    tmp[49]='\0';//on as maintenant tmp qui est remplie de 49 a (tmp[0] jusqu'à tmp[48]) et un \0 pour delimiter
    strcat(tmp,"a");//buffer overflow
    pourquoi buffer overflow?
    MAN STRCAT
    La fonction strcat() ajoute la chaîne src à la fin de la chaîne dest en écrasant le caractère nul (« \0 ») à la fin de dest, puis en ajoutant un nouveau caractère nul final. Les chaînes ne doivent pas se chevaucher, et la chaîne dest doit être assez grande pour accueillir le résultat.
    lorsque tu lis STDIN
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (read(0, env2->buffer, 4095) == 0)
    me jeter pas la pierre XD
    lire statiquement 4095 ... définie une macro ton code évolueras mieux et moins de risque de buffer overflow si tu change cette taille
    lire STDIN via read(0 ...) j'aurais mis STDIN pour la lisibilité du code
    et je revient sur ton buffer de 4096
    tu ne pourra pas lire les flèche directionnelle de cette façons ... ni mapper des touches à une fonction du style CTRL+C =afficher un magnifique message CTRL+D prévenir l'utilisateur qu'il va être deloguer et lui donné une chance de corriger son choix
    essais de lire plus caractère par caractère ton input
    si tu souhaite pouvoir faire ces chose

    P.S vu les nom de tes fonction tu ne serais pas à EPITECH?
    si oui il n'ont pas une normes niveaux taille et nom des fonctions? l'applique tu?

Discussions similaires

  1. Ajouter une aide
    Par Mailgifson dans le forum C++Builder
    Réponses: 5
    Dernier message: 12/06/2002, 13h32
  2. Besoin d'aide pour l'I.A. d'un puissance 4
    Par Anonymous dans le forum C
    Réponses: 2
    Dernier message: 25/04/2002, 17h05
  3. Une petite aide pour les API ?
    Par Yop dans le forum Windows
    Réponses: 2
    Dernier message: 04/04/2002, 21h45

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