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 :

Retrouver son prompt après un exec() Shell simple personnalisé


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Femme Profil pro
    employé
    Inscrit en
    Janvier 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Canada

    Informations professionnelles :
    Activité : employé

    Informations forums :
    Inscription : Janvier 2017
    Messages : 8
    Par défaut Retrouver son prompt après un exec() Shell simple personnalisé
    Bonjour,

    Je dois créer un Shell simple. Un prompt affiche et je peux écrire des commandes qui n'existent pas dans le vrais Bash mais qui simule leur action.

    Mais mon problème est que je sors de mon programme et j'aimerai que mon prompt s'affiche à nouveau
    je ne réussi pas à comprendre comment faire pour que suite à un execl() je puisse retrouver mon pompt
    et sortir seulement quand on écrit exit!

    j'utilise un while(1)
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <signal.h>
    #include <string.h>
    #include <sys/wait.h>
     
    int main(int argc, char *argv[]){
     
        int status;
        char buffer[500];
     
        printf("\nDans MON SHELL  écrire \"exit\" pour quitter\n");
     
        int pid = fork();
     
        if(pid == -1){
            perror("Une erreur c'est produite : création du  fork");
            return EXIT_FAILURE;
     
        }
     
        if(pid == 0){
     
            while(1){
                printf("MONSHELL > : ");
     
                scanf("%s", buffer);
     
     
                if (strcmp("exit", buffer) == 0){
                    exit(0);
     
                }else if(strcmp("dir", buffer) == 0){       //je ne retrouve pas mon promp pour entrer par exemple ctr...
     
                    execl("/bin/ls", "ls", "-l", NULL);
     
                }else if(strcmp("ctr", buffer) == 0){  
     
    	    	    execl("/usr/bin/clear", "clear", NULL);
     
    	        }else if(strcmp("environ", buffer) == 0){  
     
    	    	    execl("/usr/bin/env", "env", NULL);
     
    	        }else if(strcmp("echo", buffer) == 0){    //ici si j'écris echo cmd j'aimerai que seulement le cmd affiche....
                    printf("%s\n", &buffer);
     
                }else{
     
                    printf("Commande inconnue ...\n");
                }
            }//fin wihile
     
        }//fin if =0
     
        if(pid > 0){
     
            if(wait(NULL) == -1){
                perror("erreur de wait cote parent\n");
                exit(EXIT_FAILURE);
            }
     
        }//fin if > 0
          return EXIT_SUCCESS;
    }//fin main

    merci beaucoup
      0  0

  2. #2
    Membre expérimenté

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 329
    Par défaut
    es-tu certain qu'on atteigne à un moment le exit() ?
    j'ai l'impression que l'usage de strcmp() ne soit pas approprié dans ce contexte...
      1  0

  3. #3
    Membre expérimenté

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 329
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <signal.h>
    #include <string.h>
    #include <sys/wait.h>
     
    // Commentaires très bien ^ ^
     
    // Eviter les else if, essayer de concevoir son application pour éviter les branchements conditionnels
    // imbriqués et surtout ne pas utiliser le "else if/elsif"
     
    int main(int argc, char *argv[])
    {
        int status;
        char buffer[500];
     
    		memset(buffer,0,500);
        printf("\nDans MON SHELL  écrire \"exit\" pour quitter\n");
        int pid = fork();
     
        if(pid == -1)
    		{
            perror("Une erreur c'est produite : création du  fork");
            return EXIT_FAILURE;
        }
        if(pid == 0) // processus père
    		{
    			printf("[PERE]");		
             while(1)
    				 {
                printf("MONSHELL > : ");
                //scanf("%s", buffer);   
    						fgets(buffer,25,stdin);
    						printf("\n[DEBUG] -> %s (%s) %d\n",buffer,strcmp("exit",buffer)?"true":"false",strcmp("exit",buffer));
     
    						// Comme on ne sait pas (il y a des fonctions qui permettent de gérer plus facilement les "interpréteurs de commande"
    						// mais ici c'est "à la bonne franquette" ^^
     
    						// on teste les commandes "prises en charge" les unes après les autres, pas la peine
    						// de s'emmerder avec des else et des elsif/else if
     
                if (strstr(buffer,"exit") != NULL)
    						{
    							exit(0);
                }
                if(strstr(buffer,"dir") != NULL)
    						{       //je ne retrouve pas mon promp pour entrer par exemple ctr...
                   execl("/bin/ls", "ls", "-l", NULL);
    						}
    						if(strstr(buffer,"ctr") != NULL)
    						{  
    							execl("/usr/bin/clear", "clear", NULL);
    						}
    						if(strstr(buffer,"environ") != NULL)
    						{  
    							execl("/usr/bin/env", "env", NULL);
    						}
    						if(strstr(buffer,"echo") !=NULL)
    						{    //ici si j'écris echo cmd j'aimerai que seulement le cmd affiche....
    							printf("%s\n", &buffer);
     						}
    					}//fin wihile
     
        }//fin if =0
     
        if(pid > 0) // processus fils
    		{
    				printf("[FILS] ...");
            if(wait(NULL) == -1)
    				{
                perror("erreur de wait cote parent\n");
                exit(EXIT_FAILURE);
            }
            printf("[FILS] end...\n");
        }//fin if > 0
     
    		return EXIT_SUCCESS;
    }//fin main
    Les commentaires ont été ajoutés, j'ai utilisé strstr (qui cherche une sous-chaine dans une chaine)...
    ici strcmp() retourne toujours autre chose que 0... il est tard il fait chaud et je ne saurais pas te dire pourquoi strcmp retourne autre chose que 0.
    strstr() retourne un pointeur sur la première occurence de la chaîne trouvée dans le chaîne, ou NULL si elle n'est fait pas partie.

    Je ne sais pas pourquoi tu fais un fork(), vu que le fils attends le père et que le père lance un execl() qui remplace le code du père par le programme que tu appelles
    du coup automatiquement ton code dans le père (le while(1)...) sera remplacé par le programme exécuté par execl...
      0  0

  4. #4
    Membre expérimenté

    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2012
    Messages
    329
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2012
    Messages : 329
    Par défaut
    Bon !!
    Ton projet m'a tellement passionné que j'ai fait ceci, il faudra que tu l'adaptes, je n'ai tellement plus l'habitude des fork() que je me suis un peu emmelé les pinceaux ^ ^

    Le fork retourne 0 pour indiquer qu'il s'agit du processus "fils" et fourni le pid du processus "enfant" au processus père, je pensais que c'était l'inverse enfin bon...

    (man 3p fork: fork() shall return 0 to the child process and shall return the process ID of the child process to the parent process)

    J'avais complètement oublié que dans le "contexte des forks" il valait mieux "oublier" les fonctions "bufferisées" comme fgets() que je conseille d'utiliser, en général, pour tout ce qui concerne les "saisies au clavier".
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <signal.h>
    #include <string.h>
    #include <stdbool.h>
    #include <sys/wait.h>
     
    int main(void)
    {
    	int 	pidfils,returncode;
    	bool  bCommand=true;
    	char 	*pStrCommand;
    	char 	binarypath[255]="/usr/bin/";
     
    	pStrCommand=calloc(255,sizeof(char));
     
    	fprintf(stdout,	"Programme de test pour vérifier qu'il soit possible d'exécuter des commandes"
    									" tant que \"exit\" ne soit pas encodé...\n");
     
    	while(bCommand==true)
    	{
    		fprintf(stderr,"[SHELL]>\t");
    		//fgets(pStrCommand,255,stdin); avec l'usage de execl il vaut mieux ne pas utiliser des fonctions de type "bufferisé"... 
    		int octetslus=read(STDIN_FILENO,pStrCommand,255);
    		octetslus--;
    		*(pStrCommand+octetslus)='\0'; // on remplace le '\n' par '\0' sinon ça ne marchera pas avec execl... 		
     
    		pidfils=fork();
    		if(!pidfils) // FILS
    		{
    			fprintf(stderr,"\n[DEBUG] FILS...\n");
    			fprintf(stderr,"[FILS] pid %05d\n",pidfils);
    			fprintf(stderr,"[FILS] pStrCommand %s\n",pStrCommand);
     
    			if(strstr(pStrCommand,"exit")!=NULL) exit(1);			
    			strcat(binarypath,pStrCommand);
    			fprintf(stderr,"[FILS] binarypath %s\n",binarypath);
    			// A partir d'ici le Code Segment du processus sera remplacé par "ps" (ou n'importe quel autre programme exécutable)
    			execl(binarypath,pStrCommand,NULL);	 
     
    		}
     
    		// PERE
     
    		int code;
     
    		returncode=wait(&code);
    		if(returncode!=-1) 
    		{
    			fprintf(stderr,"[PROC DEATH] id: %05d\n",returncode);
    			if(code==256) bCommand=false; // exit(1) -> 256, exit(2) -> 512, ... exit(-1) -> 255, ... c'est un peu bizarre ^^  
    		}
    		fprintf(stderr,"[PERE] bCommand %s\n",bCommand?"true":"false");
    		strcpy(binarypath,"/usr/bin/");
    	}
    }
    Concernant la partie...

    int octetslus=read(STDIN_FILENO,pStrCommand,255);
    octetslus--;
    *(pStrCommand+octetslus)='\0'; // on remplace le '\n' par '\0' sinon ça ne marchera pas avec execl...
    ...comme nous sommes en "non bufferisé", la fonction read() incorpore le '\n' qui correspond à l'appui de la touche <RETURN> et ce caractère va nous empêcher d'exécuter execl...
    Du coup: via l'arithmétique des pointeurs je m'arrange pour placer le '\0', fin de chaîne, à la place du '\n'.

    *(pStrCommand+octetslus) <-> à partir du pointeur pStrCommand (une adresse en mémoire) tu te déplaces de octetslus * la taille du type de pStrCommand (ici 1 octet) puis à cet endroit tu y places '\0'.
    pStrCommand est l'adresse de base et octetslus est l'offset (le déplacement en mémoire) dépendant de la taille du type de pStrCommand.
    La petite étoile (dé-référencement) indique que c'est à l'adresse spécifiée qu'il faut placer le '\0'.

    C'était bien cool, j'ai pu renouer avec la fonction fork(), me rappeller que récupérer le "exit code" c'était un peu bizarre comme mécanisme, ...
      0  0

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 838
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 838
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par hurukan Voir le message
    Le fork retourne 0 pour indiquer qu'il s'agit du processus "fils" et fourni le pid du processus "enfant" au processus père, je pensais que c'était l'inverse enfin bon...
    Pourtant ça me semble à moi inoubliable ce genre de truc. Parce que si c'était l'inverse, le fils aurait un numéro qui lui sert à que dalle (son propre pid qu'il connait déjà via getpid()) et le père aurait un 0 qui lui sert aussi à que dalle et en plus ne pourrait pas connaitre le pid de son fils.

    Citation Envoyé par hurukan Voir le message
    if(code==256) bCommand=false; // exit(1) -> 256, exit(2) -> 512, ... exit(-1) -> 255, ... c'est un peu bizarre ^^
    C'est pas bizarre, c'est "construit mathématiquement" pour stocker plusieurs informatiions sur un int.

    Un processus peut s'arrêter de deux façons
    • via exit(n), n compris entre 0 et 255
    • via kill(m), m compris entre 1 et 255

    Chaque nombre "n" et "m" n'occupant qu'un octet, les deux informations accolées tiennent sur un int. Ainsi wait(&status) va attendre la fin d'un fils, et si ce fils s'est terminé par exit(n) va positionner le "n" dans les 8 premiers bits de "status" et si ce fils a été tué via kill(m), va positionner ce "m" dans les 8 derniers bits de "status".
    Ensuite il suffit de regarder. Si les 8 derniers bits sont à 0 c'est que c'était exit(n) et pour retrouver "n" suffit de faire un décalage, sinon c'était kill(m) (m ne pouvant pas être égal à 0) et pour retrouver "m" suffit là de faire un masque. Et en plus comme il est malsain d'écrire un code basé sur des conventions qui peuvent évoluer, il existe 4 macros qu'on peut utiliser pour gérer le truc et qui, elles, suivront l'évolution éventuelle
    • WIFEXITED(status) qui renvoie vrai si c'était exit(n)
    • WEXITSTATUS(status) qui renvoie la valeur du "n"
    • WIFSIGNALED(status) qui renvoie vrai si c'était kill(m)
    • WTERMSIG(status) qui renvoie la valeur du "m"

    Evidemment afficher directement "status" sans connaitre ces détails rend évidemment la chose bizarre (toutefois tu remarqueras que toutes les valeurs que tu montres dans ton exemple sont toutes égales à n * 256, ce qui équivaut à n décalé à gauche de 8 bits).
    Ne reste que le exit(-1) que tu dis valoir 255 à expliquer mais ça ça reste effectivement inexplicable parce que faux. -1 sur un bit vaut 0xff (255) et 0xff placé sur les 8 bits de gauche d'un int donnent 0xff00 soit 255 * 256 = 65280.

    Citation Envoyé par hurukan Voir le message
    Du coup: via l'arithmétique des pointeurs je m'arrange pour placer le '\0', fin de chaîne, à la place du '\n'.
    Dangereux. Parce que si l'utilisateur entre une commande qui fait pile poil 255 caractères, ta variable pStrCommand ne contient pas de '\n' et tu effaces donc le dernier caractère de la commande. Ok, peu probable je l'admets. Mais s'il existe une solution alternative qui évite cette probabilité qui, bien que très faible, n'en est pas moins concrète, alors autant l'utiliser. Et elle existe.
    Accessoirement j'en profite car c'est sur la même variable, pourquoi "calloc" pour une zone de taille fixe ??? D'autant plus que t'as oublié le free().
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #define SZ_COMMAND				(255)
    ...
    	char pStrCommand[SZ_COMMAND + 1];
    	char *pt;
    	pStrCommand[SZ_COMMAND]='\0';				// Oui, je n'ai besoin que d'un seul '\0' pour avoir une string... mais l'important est qu'il soit judicieusement positionné !!!
    	...
    	int octetslus=read(STDIN_FILENO, pStrCommand, SZ_COMMAND);	// Je t'ai conservé octetslus bien que peu utile...
    	if ((pt=strchr(pStrCommand, '\n')) != NULL) *pt='\0';
    Voilà. Désolé de te casser ta belle arithmétique des pointeurs qui en fait n'est pas vraiment utile. Toutefois elle était inutile aussi dans ton code originel. En effet, on utilise l'arithmétique des pointeurs dans des boucles de traitement, pour éviter de faire "n" fois le décalage. Mais ici, sans boucle, entre *(pStrCommand+octetslus)='\0' où tu fais une fois un décalage explicite, et pStrCommand[octetslus]='\0' qui fait exactement la même chose avec un décalage implicite là aussi qui n'est fait qu'une fois, je préfère la seconde écriture. Ben oui, à deux écritures équivalentes, mieux vaut privilégier la plus lisible...

    Citation Envoyé par hurukan Voir le message
    strcpy(binarypath,"/usr/bin/");
    Inutile. La variable n'a pas changé. Toutefois puisque j'y suis, tu concatènes une chaine pouvant aller jusqu'à 255 caractères à une chaine non nulle et tout ça dans une variable ne faisant, elle aussi, que 255 caractères...?
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define SZ_PATH				(255)
    	char binarypath[SZ_PATH + SZ_COMMAND + 1]="/usr/bin/";
    Ok, ça fait riche d'utiliser 255 caractères pour en stocker 15 mais c'est pas la mort, on peut gaspiller 240 octets (et puis si tu veux définir à moins...). Sinon l'autre solution est de faire là de l'allocation dynamique.
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #define PATH				("/usr/bin/")
    	char *binarypath=malloc(strlen(PATH) + SZ_COMMAND + 1) * sizeof(*binarypath));
    	...
    	sprintf(binarypath, "%s%s", PATH, pStrCommand);
    plus rajouter le test de réussite du malloc (ça reste impératif dans un projet réel) et ne pas oublier le free(binarypath) à la fin. Je préfère gaspiller 240 octets.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]
      2  2

  6. #6
    Membre du Club
    Femme Profil pro
    employé
    Inscrit en
    Janvier 2017
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Canada

    Informations professionnelles :
    Activité : employé

    Informations forums :
    Inscription : Janvier 2017
    Messages : 8
    Par défaut
    Merci beaucoup pour toutes les réponses!!!

    je vais prendre le temps de tout lire, de comprendre et d'essayer de coder le mieux que je peux et je vous reviens le plus vite possible!

    avec toutes les lectures et ce que vous me dites, je commence à comprendre un peu mieux ... j'ai de petites lumières qui allument

    merci encore!
      0  0

  7. #7
    Membre actif
    Homme Profil pro
    Quebec
    Inscrit en
    Octobre 2016
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Canada

    Informations professionnelles :
    Activité : Quebec
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2016
    Messages : 10
    Par défaut
    Bonsoir,

    Citation Envoyé par Sve@r Voir le message
    Bonjour
    C'est pas bizarre, c'est "construit mathématiquement" pour stocker plusieurs informatiions sur un int.
    Un processus peut s'arrêter de deux façons
    • via exit(n), n compris entre 0 et 255
    • via kill(m), m compris entre 1 et 255

    Chaque nombre "n" et "m" n'occupant qu'un octet, les deux informations accolées tiennent sur un int. Ainsi wait(&status) va attendre la fin d'un fils, et si ce fils s'est terminé par exit(n) va positionner le "n" dans les 8 premiers bits de "status" et si ce fils a été tué via kill(m), va positionner ce "m" dans les 8 derniers bits de "status".
    Ensuite il suffit de regarder. Si les 8 derniers bits sont à 0 c'est que c'était exit(n) et pour retrouver "n" suffit de faire un décalage, sinon c'était kill(m) (m ne pouvant pas être égal à 0) et pour retrouver "m" suffit là de faire un masque. Et en plus comme il est malsain d'écrire un code basé sur des conventions qui peuvent évoluer, il existe 4 macros qu'on peut utiliser pour gérer le truc et qui, elles, suivront l'évolution éventuelle.

    Evidemment afficher directement "status" sans connaitre ces détails rend évidemment la chose bizarre (toutefois tu remarqueras que toutes les valeurs que tu montres dans ton exemple sont toutes égales à n * 256, ce qui équivaut à n décalé à gauche de 8 bits).
    Ne reste que le exit(-1) que tu dis valoir 255 à expliquer mais ça ça reste effectivement inexplicable parce que faux. -1 sur un bit vaut 0xff (255) et 0xff placé sur les 8 bits de gauche d'un int donnent 0xff00 soit 255 * 256 = 65280.
    @fred , je te cite parce que je ne suis pas d'accord sur la manière dont tu te justifies par la suite. Les explications @sambia39 ne sont absolument pas en contradiction avec la tienne, il est écrit que la valeur de statut d'exit transmise au père ne tient que sur 8 bits et qu'il ne faut pas croire que cette information transmise en utilisant un type "int" est une association de valeurs. Là, il t'expose clairement qu'il s'agit des valeurs renvoyées par exit et non le cas du positionnement des bits de statuts par wait ou waitpid; il a donc parfaitement raison d’écrire que tout programme sort avec un code erreur qui tient sur 8 bits et que -1 est effectivement tronqué.

    Il ne mentionne même pas le positionnement des bits que tu décris. Il faut arrêter d’être hypocrite et vouloir penser que ce qu’il dit en te citant est en contradiction. J’ajoute que dans ce que tu écris pour le cas des signaux avec kill, seuls les 6 derniers bits sont positionnés et représentent la valeur du code retourné et l’ensemble du positionnement des bits en fonction des autres signaux n’est pas comme tu le décris, mais passons je vais pas en débatre ici sur comment wait ou waitpid fornctionne...

    Tu reconnais également qu’il n’a pas tord de te signifier que tu as fait une erreur et également il précise pourquoi ton compilateur n'a pas signalé le problème sans te frustrer dans ces explications et toi, tu lui reproches de ne pas l’écrire autrement en pensant que tu n’es pas capable de le savoir ? Sans déconner, tu l’appelles comment le débordement de tampon ? Tu aurais su toi pourquoi l’index hors tableau n’est pas détecté dynamiquement par le compilateur ?
      0  1

Discussions similaires

  1. retrouver son image perso dans messenger
    Par matrxjean1984 dans le forum Windows XP
    Réponses: 6
    Dernier message: 12/08/2006, 13h24
  2. Compte root inaccessible après changement de shell
    Par Jpountz dans le forum Administration système
    Réponses: 1
    Dernier message: 03/05/2006, 17h24
  3. [Sécurité] retrouver son mot de passe
    Par zahiton dans le forum Langage
    Réponses: 1
    Dernier message: 09/12/2005, 11h49
  4. Réponses: 3
    Dernier message: 03/02/2004, 17h34
  5. [SERVLET] retrouver son chemin
    Par sebos63 dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 12/09/2003, 08h59

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