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 :

problème de chaine de caractères


Sujet :

C

  1. #1
    Membre confirmé
    Inscrit en
    Décembre 2007
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 65
    Par défaut problème de chaine de caractères
    salut tout le monde :

    SVP est ce qu'il y a quelqu'un qui peut m'aider ,d'abord comment je remet une chaîne de caratères a NULL . elle est désactivée cette ligne dans le source.


    //for(int r=0;r<20;r++) chaine=NULL;**********************


    et 2iément si vous pouvez me rectifier mon programme
    car j'ai essayé pas mal de fois, pas d'erreurs de compilation, mais erreur de segmentation pendant l' exécution, je ne comprends pas d'où viens ça.
    merci d'avance

    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
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
     
    int main ()
    {//mettre les lien de "PATH" dans le tableau tlien
       char *path = getenv("PATH");
       char *p,*tampon;
       p = strtok_r(path,":",&tampon);
       char **tlien[10];int k=0;
       while (p != NULL)
       { 
          tlien[k]=&p;
          //printf("%s\n",*tlien[k]);
          k++;
          p = strtok_r(NULL,":",&tampon);
       } //lire la ligne de commande et mettre chaque commande dans le tableau tab;
       char comand[80],*buffer,*c,sep[]="\t;|\n";
       printf("my shell >>");
       scanf("%[^\n]",&comand);
       c = strtok_r(comand,sep,&buffer);
       char **tab[10];int i=0;
       while (c != NULL)
       {
          tab[i]=&c;
          //printf("%s\n",c);
          //printf("%s\n",*tab[i]);
          i++;
          c = strtok_r(NULL,sep,&buffer);
       }
       //vérification de l'existance des commandes tapées
       int j=0,s=0,acces=1;
       char chaine[20];
       while (j != i)
       {
          while ((s != k)&&(acces == 1))
          {
             strcat(chaine,*tlien[j]);
             strcat(chaine,"/");
             char *p,*buf,*dup;
             dup = strdup(*tab[s]);
             if (dup==NULL) dup = *tab[s];
             p = strtok_r(dup," ",&buf);
             strcat(chaine,p);
             printf("%s\n",chaine);
             if (access(chaine,F_OK)==0) acces= 0; //la commande existe
             //for(int r=0;r<20;r++) chaine=NULL; *************************
             }
          if (acces == 0) { j++; s=0;acces = 1;}
          else {printf("commande inexistante \n");break;}
       }
       return 0;
    }

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 404
    Par défaut

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for(int r=0;r<20;r++)
        chaine[r]='\0';
    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
    Membre éprouvé
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2008
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2008
    Messages : 143
    Par défaut
    Citation Envoyé par Médinoc Voir le message

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for(int r=0;r<20;r++)
        chaine[r]='\0';
    En effet, sinon la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void *memset(   void *dest,   int c,   size_t count );
    marche relativement bien il me semble (en tout cas je n'ai jamais eu de problème avec).

  4. #4
    Membre émérite Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Par défaut
    Est-ce qu'il ne suffit pas de faire :
    ?

  5. #5
    Membre confirmé
    Inscrit en
    Décembre 2007
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 65
    Par défaut
    re

    merci à vous ,moi j'ai utiliser la fontion : strcpy(chaine,""); je ne sais pas est ce que ça marche ou pas ,

    le pblme que j'ai c'est que pas d'erreurs de compilations,mais erreur de segmentation , et ça se provoque au niveau du premier appel de strcat je ne sais pas pquoi ?? si vous pouvez m'aider sachant bien que je travaille sous linux .

    et ce qu'il y'a une autre fonction qui peut me servir ,et qui m'evite ce genre de pblme .

    merci encore une fois

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par laracroft87 Voir le message
    merci à vous ,moi j'ai utiliser la fontion : strcpy(chaine,""); je ne sais pas est ce que ça marche ou pas ,
    oui ça marche, et c'est strictement équivalent à ce qu'a écrit crocodilex.

    Il faut cependant être conscient que ça n'initialise pas l'ensemble des caractères. Pour ça, c'est soit memset (le plus court) soit une boucle.

    • Déjà, outre le fait que déclarer les variables en plein milieu du code est illisible, sauf si c'est dans des blocs (entourés par des accolades), ce n'est autorisé que en C99, et c'est rigoureusement interdit avant.

    • Ensuite, main est une fonction qui prend soit 0 argument, auquel cas on la déclares int main(void), soit 2 arguments, auquel cas on la déclare int main(int argc, char **argv)


    Je n'ai regardé le reste qu'en diagonale, bien qu'il me semble qu'il y aie un certain nombre d'erreurs majeures (dont char **tlien[10] mais un effort de présentation serait souhaitable tout d'abord.

  7. #7
    Membre éprouvé
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2008
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2008
    Messages : 143
    Par défaut
    Citation Envoyé par laracroft87 Voir le message
    re

    merci à vous ,moi j'ai utiliser la fontion : strcpy(chaine,""); je ne sais pas est ce que ça marche ou pas ,

    le pblme que j'ai c'est que pas d'erreurs de compilations,mais erreur de segmentation , et ça se provoque au niveau du premier appel de strcat je ne sais pas pquoi ?? si vous pouvez m'aider sachant bien que je travaille sous linux .

    et ce qu'il y'a une autre fonction qui peut me servir ,et qui m'evite ce genre de pblme .

    merci encore une fois
    Un erreur de segmentation viens du fait que tu dois surement dépasser la capacité de ton tableau.

    Déjà, outre le fait que déclarer les variables en plein milieu du code est illisible, sauf si c'est dans des blocs (entourés par des accolades), ce n'est autorisé que en C99, et c'est rigoureusement interdit avant.
    En effet, c'est pas bien beau tout ça :p

    De plus essaye de donner des "NOM" a tes variable on comprendrai mieux ce qu'elles doivent faire :p

    Aussi j'ajouterais que tu dois avoir la possibilité de "virer" quelques variables, j'imagine que t'en a une ou deux que tu n'utilise qu'une fois ?


    PS : Est-on sûr que le STRCPY soit vraiment plus rapide et compréhensible qu'un bon vieux chaine[0]='\0' ??

  8. #8
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par laracroft87 Voir le message
    le pblme que j'ai c'est que pas d'erreurs de compilations,mais erreur de segmentation , et ça se provoque au niveau du premier appel de strcat je ne sais pas pquoi ??
    chaine n'est pas initialisée, il y a donc peu de chance que strcat() trouve un '\0' d'où un probable débordement de buffer.

  9. #9
    Membre confirmé
    Inscrit en
    Décembre 2007
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 65
    Par défaut
    re

    mon pblme réside dans la fontion strcat,c elle qui me provoque l' erreur de segmentation car quand j'ai testé le programme se plante dés le premier appel de cette fontion ,et le char **tlien[] j'ai pas de pblme avec ,c'est pour mettre de-dans des pointeurs de chaine de caractére .
    j'ai retouché le code encore une fois et voici le :

    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
     
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    int main ()
    {//mettre les lien de "PATH" dans le tableau tlien
    char *path = getenv("PATH");
    char *p=NULL;
    char *tampon=NULL;
    p = strtok_r(path,":",&tampon);
    char **tlien[10];
    int k=0;
    while (p != NULL)
    { tlien[k]=&p;
    //printf("%s\n",*tlien[k]);
    k++;
    p = strtok_r(NULL,":",&tampon);
    }
    //lire la ligne de commande et mettre chaque commande dans le tableau tab;
    char comand[80];
    char *buffer;
    char *c;
    char sep[]="\t;|\n";
    printf("my shell >>");
    scanf("%[^\n]",comand);
    char *comdup=strdup(comand);
    c = strtok_r(comdup,sep,&buffer);
    char **tab[10];int i=0;
    while (c != NULL)
    {
    tab[i]=&c;
    printf("%s\n",c); //****************
    printf("%s\n",*tab[i]);//***************
    i++;
    c = strtok_r(NULL,sep,&buffer);
    }
    //vérification de l'existance des commandes tapées
    int j=0,s=0,acces=1,a=0;
    char chaine[20]="";
    char **lien[40];
    while (j != i)
    {
    while ((s != k)&&(acces == 1))
    { printf("%d,%d,%d,%d\n",i,j,s,k);
    strcat(chaine,*tlien[j]);//@@@@@@@@@@@@@@@@@@@@@@@@@@@@ le
    pblme est là
    strcat(chaine,"/");
    printf("%s\n",chaine); //****************** juste pour le test
    char *p;
    char *buf;
    char *dup;
    dup = strdup(*tab[s]);
    if (dup==NULL) dup = *tab[s];
    p = strtok_r(dup," ",&buf);
    strcat(chaine,p);
    printf("%s\n",chaine); //********************** juste pour le test
    if (access(chaine,F_OK)==0)
    {
    acces= 0;
    *lien[a]=chaine; //la commande existe ************************** lien[a]=&chaine
    a++;
    }
    strcpy(chaine,"");
    }
    if (acces == 0) { j++; s=0;acces = 1;}
    else {printf("commande inexistante \n");break;}
    }
    return 0;
    }
    SVP essaié de le voir et me dire pquoi !!
    merci a vous

  10. #10
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Juste un petit conseil, un code bien présenté (indenté) est plus facile à lire et à comprendre. Le code tel que tu le présentes n'incite pas à se plonger dedans.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  11. #11
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Pourrais-tu commencé par faire un effort dans la présentation de ton code et dans a rédaction de tes messages.
    Il est plutôt désagréable d'essayer de déchiffrer ce que tu cherches à faire

    Citation Envoyé par laracroft87 Voir le message
    mon pblme réside dans la fontion strcat,c elle qui me provoque l' erreur de segmentation car quand j'ai testé le programme se plante dés le premier appel de cette fontion ,et le char **tlien[] j'ai pas de pblme avec ,c'est pour mettre de-dans des pointeurs de chaine de caractére.
    J'avoue que j'ai quand même du mal à voir ce que tu cherches à faire avec ce char **tlien[]. D'autant plus que tu y met toujours l'adresse de p qui ne change pas, tous les éléments du tableau vont donc contenir la même adresse (qui est celle de p). Or à la fin de la boucle p == NULL donc *tlien[j] == NULL ce qui pose clairement problème.

  12. #12
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Diverses remarques sur ton programme (certaines déjà signalées par ailleurs) :

    • Améliore l'indentation de ton programme, ce qui lui permettra d'être plus lisible.
    • Utilise des noms de variables significatifs.
    • Découpe le programme en fonctions élémentaires.
    • Réduit au maximum la portée des variables.
    • Quand tu commences à avoir plusieurs niveaux d'indirection (au hasard char **tlien[10], reprends calmement ton code, il est fort probable que ce soit une erreur ou que le code est inutilement compliqué.
    • L'utilisation de scanf() est incorrecte (pas de vérification de la valeur de retour, pas de vérification de la taille saisie, etc.). Ici scanf() pourra avantageusement être remplacer par fgets().
    • Après une saisie clavier, il serait bien de vider, si nécessaire, le buffer d'entrée.
    • Il n'y a pas de vérification de la taille du buffer avec strcat() (d'où un risque de débordement). Cette fonction pourra avantageusement être remplacé par strncat().
    • Pourquoi utiliser break pour sortir de la boucle while ?
    • Tu ne vérifies pas les bornes de tes tableaux das tes boucles, il y a un risque de dépassement.
    • Tu utilise la variable s comme index de tableau mais s ne semble n'être jamais modifié.
    • Ta construction autour de strdup() me semble douteuse.

  13. #13
    Membre éprouvé
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2008
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2008
    Messages : 143
    Par défaut
    Voila, alors je dit pas que ce soit forcément mieux...
    mais déjà je pense avoir régler quelque problème mineur.

    Peut-être que certains ne trouverons pas cela "jolie" peut-être même illisible :p

    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
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
     
    //DEUX façons de déclarer le MAIN :
    //		- int main (int argc, char **argv)
    //		- int main (void)
    // et non pas int main() !!!
    //fais un éffort de présentation s'il te plait !
    int main (void)
    {
     
    	char *pStringSeg;
    	char *tampon;
    	char **tlien[10];
    	int nCmdTotal=0,j=0,s=0,acces=1,nbCommand=0;
    	int cmdCounter=0;
    	char *lien[40];
    	char *comdup;
    	char **tab[10];
     
    //tu met tout les 'lien' de PATH dans path
    #define path	(char *) comdup
    	path = getenv("PATH");
    	pStringSeg = strtok_r(path,":",&tampon);
    #undef path
     
    	//on test pStringSeg sinon on continuerai probablement avec des conneries...
    	if(!pStringSeg) return -1;
     
    //mettre les lien de "PATH" dans le tableau tlien	
    	while (pStringSeg != NULL)
    	{
    		//met le nCmdTotal'ieme' lien dans le tableau
    		tlien[nCmdTotal]=&pStringSeg;
    		nCmdTotal++;
    		//passe au lien suivant
    		pStringSeg = strtok_r(NULL,":",&tampon);
    	}
     
    	//lire la ligne de commande et mettre chaque commande dans le tableau tab;
    #define command (char *)tampon
    	command=(char*)calloc(80,sizeof(char));
    	if(!command)return -1;
     
    	printf("my shell >>");
     
    	//si l'entrée standard et remplace le retour chariot par un 0.
    	fgets(command,79,stdin);
    	pStringSeg=strchr(command,'\n');
    	if(pStringSeg) pStringSeg='\0';
     
    	//vide le buffer d'entrée standard.
    	fflush(stdin);
     
    	//strdup retourne une adresse. donc pas *comdup=...
    	comdup=strdup(comand);
    	if(!comdup) return -1;
    	//on libère l'espace mémoire
    	free(command);
    #undef command
     
    	pStringSeg = strtok_r(comdup,"\t;|\n",&tampon);
    	while (c != NULL)
    	{
    		tab[cmdCounter]=&pStringSeg;
    		printf("%s\n",pStringSeg);
    		printf("%s\n",*tab[cmdCounter]);
    		cmdCounter++;
    		pStringSeg = strtok_r(NULL,"\t;|\n",&tampon);
    	}
     
    //vérification de l'existance des commandes tapées
    	memset(lien[nbCommand],'\0',20);
     
    	while (j != cmdCounter)
    	{
    		while ((s != nCmdTotal)&&(acces == 1))
    		{ 
     
    			printf("%d,%d,%d,%d\n",cmdCounter,j,s,nCmdTotal);
    			strncat(lien[nbCommand],*tlien[j],strlen(*tlien[j]));
    			strncat(lien[nbCommand],"/",strlen("/");
     
    			comdup = strdup(*tab[s]);
    			if (comdup==NULL) comdup = *tab[s];
    			pStringSeg = strtok_r(comdup," ",&tampon);
    			strncat(lien[nbCommand],pStringSeg,strlen(pStringSeg));
     
    			if (access(lien[nbCommand],F_OK)==0)
    			{
    				acces= 0;
    				nbCommand++;
    			}
    			memset(lien[nbCommand],'\0',20);
    			s++;//je met ça mais après moi je sais pas trop peut-être veux-tu continuer perpetuellement ?
    		}
    		if (acces == 0) 
    		{ 
    			j++; 
    			s=0;
    			acces = 1;
    		}
    		else 
    		{
    			printf("commande inexistante \n");
    			break;
    		}
    	}
    	return 0;
    }
    Ha, je n'ai pas testé la compilation :s

    Aussi faut-il dire que de t'aider sans réellement savoir ce que tu vas faire etc... par exemple il ce peut que tu utilises un programme bien plus long et que tu ne nous ai montré qu'une partie donc les variable que j'ai modifier vont peut être poser problème pour toi ...

  14. #14
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par rilou Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define path	(char *) comdup
    Curieuse pratique que de définir de tel alias sur des variables avec le préprocesseur. Pourquoi ne pas utiliser la variable initiale quitte à, si le problème est le nom, la renommer ?

    Citation Envoyé par rilou Voir le message
    Voila, alors je dit pas que ce soit forcément mieux...
    Je confirme ce n'est pas beaucoup mieux:
    • Pourquoi "return -1", la norme ne définie que EXIT_SUCCESS, EXIT_FAILURE et 0. Autant retourner une valeur portable, EXIT_FAILURE dans le cas présent.
    • command=(char*)calloc(80,sizeof(char)); : pourquoi caster le retour avec char* ? Pourquoi utiliser sizeof(char) et non sizeof *command ? Et surtout pourquoi faire une allocation dynamique d'une variable dont la taille est connue à la compilation et reste relativement petite ?
    • if(!command) : préféré "if(command == NULL)", c'est beaucoup plus lisible.
    • fgets(command,79,stdin); : pourquoi 79 ? En outre, si on remplace l'allocation dynamique par un tableau statique comme indiqué précédemment, ça devient "sizeof command", beaucoup plus évolutif.
    • fflush(stdin); : le comportement est défini. La norme ne définie le comportement de fflush() que sur les flux sortant. Pour avoir un programme portable, il ne faut pas utiliser fflush(stdin); mais commencer les caractères restants. En outre il n'est pas utile de vider le buffer si le caractère '\n' a été lu.
    • memset(lien[nbCommand],'\0',20); : pourquoi 20 ? lien[nbCommand][0] = '\0' suffit.
    • strncat(lien[nbCommand],*tlien[j],strlen(*tlien[j])); : ce n'est pas la taille de la chaîne à copier qu'il faut utiliser (surtout pas en oubliant le '\0' terminal) mais la taille maximale copiable (afin de gérer le non-débordement du buffer). Ce que tu as écrit revient à utiliser strcat().
    • Il est préférable de ne pas utiliser de caractères accentués dans les commentaires.

  15. #15
    Membre éprouvé
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2008
    Messages
    143
    Détails du profil
    Informations personnelles :
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2008
    Messages : 143
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    strncat(lien[nbCommand],*tlien[j],strlen(*tlien[j]));
    : ce n'est pas la taille de la chaîne à copier qu'il faut utiliser (surtout pas en oubliant le '\0' terminal) mais la taille maximale copiable (afin de gérer le non-débordement du buffer). Ce que tu as écrit revient à utiliser strcat().
    je suis d'accord mais après lors de la déclaration des tableau on peut lire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char *lien[40];
    char **tlien[10];
    donc on risque de recopier (si on met 40 dans strncat) le contenu du tableau tlien ainsi que ce qui se trouve après non (vu qu'il ne fait que 10)??

    Pourquoi "return -1", la norme ne définie que EXIT_SUCCESS, EXIT_FAILURE et 0. Autant retourner une valeur portable, EXIT_FAILURE dans le cas présent.
    ...
    fflush(stdin); : le comportement est défini. La norme ne définie le comportement de fflush() que sur les flux sortant.
    ...


    Merci des renseignements !


    memset(lien[nbCommand],'\0',20); : pourquoi 20 ? lien[nbCommand][0] = '\0' suffit.
    On ne sait jamais, au moins on est sûr que toute les 'cases' sont à 0. Il ce peut que dans une future manipulation de son code il éprouve un besoin d'utiliser autre chose que l'indice 0 et dans ce cas il trouverait une valeur != 0


    command=(char*)calloc(80,sizeof(char)); : pourquoi caster le retour avec char* ?
    Mauvaise habitude probablement... mon compilateur (mal régler me direz vous) aime crier lorsque je ne met pas ça :s

    Et surtout pourquoi faire une allocation dynamique d'une variable dont la taille est connue à la compilation et reste relativement petite ?
    Car dans notre cas tampon devra servir de " char ** " et donc faire une allocation dynamique dessus permettra de libérer la mémoire ultérieurement.


    Curieuse pratique que de définir de tel alias sur des variables avec le préprocesseur. Pourquoi ne pas utiliser la variable initiale quitte à, si le problème est le nom, la renommer ?
    Je trouve, ET CELA N'ENGAGE QUE MOI (alors pas de débat hein...) que dans l'utilisation que j'en ai fait et avec les noms de variable utilisés cela ne gène pas la compréhension globale du programme.

    Je pense que cette "pratique" permet de pouvoir renommer au cas par cas (lors d'utilisations précises) une variable, plutôt que d'en déclarer trois ou quatre et ainsi pouvoir avoir des nom clair des variables utilisé dans un cas précis et ce pour un BLOQUE précis.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fgets(command,79,stdin);
    Mauvaise interprétation :s navré.


    Je confirme ce n'est pas beaucoup mieux
    Ca c'est méchant :p, non plus sérieusement : merci des remarques, j'apprécie.
    C'est d'ailleurs pour ce genre de remarques que je viens poster sur ce forum.

    Aider les autres (ou au moins essayer) tout en lisant des commentaires (constructifs !) sur " l'aide " qu'on tente d'apporter. Ca nous enrichie, vous (je l'espère) et nous aussi.



    De plus je tiendrait à ajouter que compte tenu du "NON-EFFORT" que la personne a fournis pour la présentation de son problème, même si mon code n'est pas parfait, et beh au moins j'ai tenté d'aider et rendu son code sûrement plus lisible...enfin j'espère.


    Bonne soirée

  16. #16
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par rilou Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    strncat(lien[nbCommand],*tlien[j],strlen(*tlien[j]));
    : ce n'est pas la taille de la chaîne à copier qu'il faut utiliser (surtout pas en oubliant le '\0' terminal) mais la taille maximale copiable (afin de gérer le non-débordement du buffer). Ce que tu as écrit revient à utiliser strcat().
    je suis d'accord mais après lors de la déclaration des tableau on peut lire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char *lien[40];
    char **tlien[10];
    donc on risque de recopier (si on met 40 dans strncat) le contenu du tableau tlien ainsi que ce qui se trouve après non (vu qu'il ne fait que 10)??
    Pas de risque, la copie s'arrêtera sur le '\0' terminal dans ce cas.

    Citation Envoyé par rilou Voir le message
    memset(lien[nbCommand],'\0',20); : pourquoi 20 ? lien[nbCommand][0] = '\0' suffit.
    On ne sait jamais, au moins on est sûr que toute les 'cases' sont à 0. Il ce peut que dans une future manipulation de son code il éprouve un besoin d'utiliser autre chose que l'indice 0 et dans ce cas il trouverait une valeur != 0
    Ici, command est une chaîne de caractère, initialiser le premier octet est suffisant.
    Dans le cas d'un simple tableau et non d'une chaîne de caractère, effectivement il faut initialiser tous les champs.

    Citation Envoyé par rilou Voir le message
    command=(char*)calloc(80,sizeof(char)); : pourquoi caster le retour avec char* ?
    Mauvaise habitude probablement... mon compilateur (mal régler me direz vous) aime crier lorsque je ne met pas ça :s
    A priori tu dois compiler en C++ et non en C.

    Citation Envoyé par rilou Voir le message
    Et surtout pourquoi faire une allocation dynamique d'une variable dont la taille est connue à la compilation et reste relativement petite ?
    Car dans notre cas tampon devra servir de " char ** " et donc faire une allocation dynamique dessus permettra de libérer la mémoire ultérieurement.
    Effectivement, j'avais zapper l'alias sur le nom. Une réduction de la portée des variables couplé à un choix judicieux des noms de variables (ainsi qu'un décupage en fonction simple) est suffisant et plus idiomatique.
    Et permet en outre une réutilisation plus simple.

    Citation Envoyé par rilou Voir le message
    Curieuse pratique que de définir de tel alias sur des variables avec le préprocesseur. Pourquoi ne pas utiliser la variable initiale quitte à, si le problème est le nom, la renommer ?
    Je trouve, ET CELA N'ENGAGE QUE MOI (alors pas de débat hein...) que dans l'utilisation que j'en ai fait et avec les noms de variable utilisés cela ne gène pas la compréhension globale du programme.

    Je pense que cette "pratique" permet de pouvoir renommer au cas par cas (lors d'utilisations précises) une variable, plutôt que d'en déclarer trois ou quatre et ainsi pouvoir avoir des nom clair des variables utilisé dans un cas précis et ce pour un BLOQUE précis.
    Ce n'est pas vraiment idiomatique et donc nuit a la lecture et à la compréhension.
    Pou la réduction de la visibilité du nom à un bloc de code, c'est effectivement une bonne pratique, mais autant créer de vrai bloc (voire des fonctions) et limiter la portée des variables.

    Citation Envoyé par rilou Voir le message
    Je confirme ce n'est pas beaucoup mieux
    Ca c'est méchant :p
    Ce n'était pas du tout mon intention.

Discussions similaires

  1. Problème avec chaine de caractères
    Par Nicegame dans le forum C
    Réponses: 7
    Dernier message: 27/04/2007, 19h35
  2. problème de chaine de caractère
    Par franco82 dans le forum C++
    Réponses: 10
    Dernier message: 01/12/2006, 21h32
  3. Problème fonctions chaines de caractères.
    Par Hayron06 dans le forum C
    Réponses: 12
    Dernier message: 13/11/2006, 22h47
  4. [MySQL] problème de chaine de caractère
    Par Leinad dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 18/10/2006, 15h52
  5. [FLASH 8] Problème de chaine de caractère
    Par dom_dev dans le forum Flash
    Réponses: 7
    Dernier message: 02/03/2006, 18h42

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