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 :

créer un tableau dynamique


Sujet :

C

  1. #1
    Candidat au Club
    créer un tableau dynamique
    bonjour,
    J'essaye de créer un programme qui permet à l'utilisateur d'ajouter ,supprimer ,ou modifier un élément dans un tableau dynamique.
    J'ai un problème concernant l'ajout d'un élément . Veuiller m'aider à le résoudre .
    MERCII.
    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
     
    #include <stdio.h>
    #include <stdlib.h>
     
    void menu()
    {
    		printf("\n1- ajouter une valeur.\n2- modifier une valeur.\n3- supprimer une valeur.\n4- lister.\n5- quitter.\n");
    }
    void ajouterval(int *t,int &taille)
    {	int val;
    	printf("donner une valeur: ");
    	scanf("%d",&val);
    	if(taille==0)
    	{
    		t=(int*)malloc(sizeof(int)*taille);
    		t[taille]=val;
    		taille++;
    	}
    	else
    	{	
    		realloc(t,sizeof(int)*taille+1);
    		t[taille]=val;
    		taille++;
    	}
    }
    void modifier(int *t,int taille)
    {	int pos=-1;int nval;int val;
    	if(taille==0)
    	{
    		printf("tableau est vide!");
    	}
    	else
    	{	
    		printf("donner la valeur a modifier: ");
    		scanf("%d",&val);
    		for(int i=0;i<taille;i++)
    		{
    			if(t[i]==val)
    			{
    				pos=i;
    				i=taille;
    			}
    		}
    		if(pos!=-1)
    		{
    				printf("donner la nouvelle valeur: ");
    				scanf("%d",&nval);
    				t[pos]=nval;
    		}
    		else
    		{
    			printf("valeur n'existe pas!");
    		}
    	}
    }
    void supprimer(int *t,int &taille)
    {
    	int val;int pos=-1;
    	printf("donner la valeur a supprimmer: ");
    	scanf("%d",&val);
    	for(int i=0;i<taille;i++)
    	{
    		if(t[i]==val)
    		{
    			pos=i;
    			i=taille;
    		}
    	}
    	if(pos!=-1)
    	{
    		for(int i=pos;i<taille-1;i++)
    		{
    			t[i]=t[i+1];
    		}
    		realloc(t,sizeof(int)*taille-1);
    		taille--;
    	}
    	else
    	{
    		printf("l'element n'existe pas!");
    	}
    }
    void lister(int *t,int taille)
    {
    	if(taille==0)
    	{
    		printf("le tableau est vide!\n");
    	}
    	else
    	{
    		for(int i=0;i<taille;i++)
    		{
    			printf("t[%d]=%d  ",i,t[i]);
    		}
    	}
    }
     
    main()
    {
    	int *t=NULL;int taille=0;int choix;
    	do
    	{
     
    		system("cls");
    		menu();
    		printf("donner votre choix: ");
    		scanf("%d",&choix);
    		switch(choix)
    			{
    				case 1:ajouterval(t,taille);break;
    				case 2:modifier(t,taille);break;
    				case 3:supprimer(t,taille);break;
    				case 4:lister(t,taille);break;
    				case 5:printf("fin du programme!");
    			}
    		system("pause");
    	}while(choix!=5);
    return 0;
    }

  2. #2
    Expert confirmé
    Bonjour,

    Pour obtenir une réponse précise, il faudrait une question précise.
    J'ai quand même lu quelques lignes, je me suis arrêté ligne 15 où si taille vaut zéro alors tu alloues zéro octets tu tentes d'écrire dedans, ça n'ira pas loin.

  3. #3
    Candidat au Club
    merci pour votre réponse, et veuiller etre patient avec moi car je ne sais pas bien s'exprimer en francais.
    J'ai supprimé "taille" qui se trouve dans la ligne 15 et ca marche.mais quand j'essaye d'ajouter une autre valeur ou bien modifier ou supprimer une valeur existante le programme s'arrete.

  4. #4
    Membre habitué
    A mon avis tu devrais plutôt passer par une liste chaînée. C'est vrai que la mise en place nécessite un peu plus de boulot, mais une fois que c'est au point tu gagneras du temps.

    Cependant la liste chaînée nécessite une connaissance des structures et des pointeurs (pour parcourir la liste -- elle peut être doublement chaînée ce qui complexifie un peu le mécanisme).

    En gros:

    Tu écris une structure qui définit une liste, par exemple:

    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
    typedef struct item_Datas
    {
    	unsigned int        item_Number;
    	unsigned int        dataSize;
    	int  dataType;
    	struct item_Datas   *pPrevious;
    	struct item_Datas   *pNext;
     
    	void	*value;
     
      // pointeurs de fonction
    	void                (*pDisplay)(void*);												// pour pouvoir afficher des données du standard ANSI C et celles définies par l'utilisateur...
    	void			(*pFree)(void*);
    }lc_Datas;
     
    typedef struct 
    {
    	unsigned int	NbElem;
    	lc_Datas    *pHead;
    	lc_Datas    *pTail;
    }ListeChainee;


    ...ceci est extrait d'une de mes librairies... (https://github.com/truesoundlord/saintmartin)

    Cela permet de manipuler n'importe quel type de données dans une liste doublement chaînée (on peut la parcourir dans les deux sens de la tête à la queue et inversément).

    Il faut donc prévoir plusieurs fonctions:

    une pour initialiser la liste;
    une pour gérer les files fifo et lifo (insérer en tête de liste, ou en queue de liste) (si les données doivent être triées il vaut mieux utiliser les fonctions liées à stdlib.h, qsort(), bsearch(), ...)
    une pour effacer un élément de la liste en se basant sur son identifiant ou sa valeur (pour sa valeur chez moi c'est pas encore vraiment au point, mais j'ai des résultats)
    une pour enlever le premier élément de la liste (FIFO);
    une pour vider la liste;

    ...c'est du boulot mais à mon avis tu pourrais réutiliser ces concepts dans tous tes programmes futurs.

  5. #5
    Expert éminent sénior
    Bonjour
    Citation Envoyé par chi5nano Voir le message
    J'ai supprimé "taille" qui se trouve dans la ligne 15 et ca marche.mais quand j'essaye d'ajouter une autre valeur ou bien modifier ou supprimer une valeur existante le programme s'arrete.
    Plusieurs remarques
    • quand on te dit "ici ça ne va pas", ce n'est pas en supprimant la ligne que ça va aller mieux. Il faut que tu réfléchisses à pourquoi tu as écrit cette ligne. Elle voulait sûrement dire quelque chose pour toi et si elle ne va pas (parce qu'une valeur vaut 0), il faut la corriger et non pas la supprimer. Ou alors s'il faut vraiment la supprimer alors tu dois tout repenser derrière au code qui devra fonctionner sans ce que tu espérais de cette ligne
    • int &taille de la ligne 9 ce n'est pas du C. Du C++ peut-être mais ici on est dans le forum C. Si ton souci est en C++ tu dois aller le poster dans le forum C++ où tu obtiendras des solutions C++ (peut-être à base de new[] au lieu de malloc par exemple)
    • malloc renvoie l'adresse de la zone allouée. Ok, tu récupères cette adresse là ça va. realloc fait la même chose donc tu dois récupérer aussi cette adresse puis remplacer la précédente (celle du malloc ou du realloc précédent) par la nouvelle. Accessoirement tu peux te passer de malloc en appelant realloc avec NULL en premier paramètre. Dans ce cas, le realloc se comporte comme malloc
    • au lieu de tout coder d'un coup puis de faire ton test final (qui s'écroule), code une fonction après l'autre. Tu codes l'insertion, tu testes l'insertions. Puis tu codes la suppression et tu la testes. Et etc etc

    Sinon pour optimiser
    • le menu pourrait en plus faire saisir le choix et le renvoyer ce qui éviterait d'avoir à écrire ces instructions chaque fois que tu appelles le menu
    • comme realloc peut être assez long, pour ne pas avoir à l'appeler à chaque nouvel élément tu pourrais gérer une "taille allouée" et une "taille utilisée". Tu alloues N puis ensuite tu remplis au fur et à mesure. Et dès que la taille remplie atteint N, là tu réalloues N de plus


    Citation Envoyé par hurukan Voir le message
    A mon avis tu devrais plutôt passer par une liste chaînée. C'est vrai que la mise en place nécessite un peu plus de boulot, mais une fois que c'est au point tu gagneras du temps.
    C'est vrai mais je pense qu'il n'a pas encore le niveau...
    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

  6. #6
    Membre habitué
    C'est vrai mais je pense qu'il n'a pas encore le niveau...
    Nous allons l'aider à penser sa solution.
    En plus si la français c'est pas sa langue natale c'est pas évident pour lui.

    J'ai écrit une fonction il y a longtemps permettant de créer un tableau dynamiquement, je vais relire le code source (librairie uepwide, fonction getnchar() sur github).
    Au moins il aura une "base" (je n'ai pas encore testé complètement dans l'environnement Windows) mais cette fonction me donne l'impression de fonctionner (bon il y a eu des modifs je ne sais plus trop pour quelles raisons et j'ai remarqué deux trois petites choses bizarres que je ne sais
    plus expliquer aujourd'hui ^^ ).

    [EDIT]

    "permettant de créer un tableau dynamiquement" est une vue de l'esprit...
    Cette fonction permet de signaler la taille maximum d'un tableau mais le côté "dynamique" réside uniquement dans le fait qu'on utilise un pointeur sur char au lieu des crochets.

    exemple d'utilisation:

    char *machaine=getnchar(20); // permet de saisir une chaîne de caractères de maximum 20 caractères (utf8/unicode compris).

  7. #7
    Expert éminent sénior
    Citation Envoyé par hurukan Voir le message
    char *machaine=getnchar(20); // permet de saisir une chaîne de caractères de maximum 20 caractères (utf8/unicode compris).
    A priori, ça ne semble pas bien difficile...
    Code c :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    char *getnchar(const size_t n) {
    	char *zone=malloc((n+1) * sizeof(char));
    	if (zone != NULL) fgets(zone, n+1, stdin);
    	return zone;
    }

    Ensuite on peut rajouter le flux en paramètre ou un prompt pour que ça ait plus d'allure. Sinon il y a getline() qui fait pareil mais en mieux...
    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

  8. #8
    Membre habitué
    ^^ oui getline() j'ai rencontré son existance qu'APRES avoir écrit ma fonction lol ^^

  9. #9
    Candidat au Club
    je vous remercie tous pour votre aide même si franchement je n'est pas bien compris vos suggestions.
    je crois que je j'ai besoin a beaucoup apprendre afin de suivre avec vous.
    cette semaine j'ai assisté à la première séance du cours concernant les pointeurs et le prof nous a demandé d'essayer de résoudre ce problème même si on aura des difficultés.
    aujourd'hui j'ai montré au prof la procédure de "ajouterval" et il m'a dit qu'il vaut mieux l'utiliser comme fonction pour des raisons qu'on va voir à la prochaine séance.
    voici la nouvelle version du 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
    124
    125
    126
    127
     
    #include <stdio.h>
    #include <stdlib.h>
     
    void menu()
    {
    		printf("\n1- ajouter une valeur.\n2- modifier une valeur.\n3- supprimer une valeur.\n4- lister.\n5- quitter.\n");
    }
    int * ajouterval(int *t,int &taille)
    {	int val;
    	printf("donner une valeur: ");
    	scanf("%d",&val);
    	if(taille==0)
    	{
    		t=(int*)malloc(sizeof(int));
    		t[taille]=val;
    		taille++;
    	}
    	else
    	{	
    		realloc(t,sizeof(int)*(taille+1));
    		t[taille]=val;
    		taille++;
    	}
    	return t;
    }
    void modifier(int *t,int taille)
    {	int pos=-1;int nval;int val;
    	if(taille==0)
    	{
    		printf("tableau est vide!\n");
    	}
    	else
    	{	
    		printf("donner la valeur a modifier: ");
    		scanf("%d",&val);
    		for(int i=0;i<taille;i++)
    		{
    			if(t[i]==val)
    			{
    				pos=i;
    				i=taille;
    			}
    		}
    		if(pos!=-1)
    		{
    				printf("donner la nouvelle valeur: ");
    				scanf("%d",&nval);
    				t[pos]=nval;
    		}
    		else
    		{
    			printf("valeur n'existe pas!\n");
    		}
    	}
    }
    void supprimer(int *t,int &taille)
    {
    	int val;int pos=-1;
    	if(taille==0)
    	{
    		printf("le tableau est vide!\n");
    	}
    	else
    	{
    		printf("donner la valeur a supprimer: ");
    		scanf("%d",&val);
    	for(int i=0;i<taille;i++)
    	{
    		if(t[i]==val)
    		{
    			pos=i;
    			i=taille;
    		}
    	}
    	if(pos!=-1)
    	{
    		for(int i=pos;i<taille-1;i++)
    		{
    			t[i]=t[i+1];
    		}
    		realloc(t,sizeof(int)*(taille-1));
    		taille--;
    	}
    	else
    	{
    		printf("l'element n'existe pas!\n ");
    	}
    	}
    }
    void lister(int *t,int taille)
    {
    	if(taille==0)
    	{
    		printf("le tableau est vide!\n");
    	}
    	else
    	{
    		for(int i=0;i<taille;i++)
    		{
    			printf("t[%d]=%d  ",i,t[i]);
    		}
    	}
    }
     
    main()
    {
    	int *t=NULL;int taille=0;int choix;
    	do
    	{
     
    		system("cls");
    		menu();
    		printf("donner votre choix: ");
    		scanf("%d",&choix);
    		switch(choix)
    			{
    				case 1:t=ajouterval(t,taille);break;
    				case 2:modifier(t,taille);break;
    				case 3:supprimer(t,taille);break;
    				case 4:lister(t,taille);break;
    				case 5:printf("fin du programme!\n");
    			}
    		system("pause");
    	}while(choix!=5);
    return 0;
    }

  10. #10
    Expert éminent sénior
    Citation Envoyé par chi5nano Voir le message
    voici la nouvelle version du code:
    Ca reste du C++ (le &taille). Et t'as pas récupéré le retour de realloc (tu réalloues dans le vide). Et puis franchement, essaye un peu d'aérer ton code. T'as vraiment besoin de tout serrer comme tu le fais ?
    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
    #include <stdio.h>
    #include <stdlib.h>
     
    int menu() {
    	int choix;
    	char *liste[]={
    		"1- ajouter une valeur.",
    		"2- modifier une valeur.",
    		"3- supprimer une valeur.",
    		"4- lister.",
    		"0- quitter.",
    		NULL,
    	};
    	char **pt;
     
    	printf("\nMenu\n");
    	for (pt=liste; *pt != NULL; pt++)
    		printf("%s\n", *pt);
    	printf("donner votre choix: ");
    	scanf("%d", &choix);
    	return choix;
    }
     
    int chercheVal(int *t, int taille, int val) {
    	for (int i=0; i < taille; i++) {
    		if (t[i] == val) return i;
    	}
    	return -1;
    }
     
    int *ajouterval(int *t, int *taille) {
    	int val;
    	printf("donner une valeur: ");
    	scanf("%d", &val);
    	t=realloc(t, sizeof(int)*((*taille)+1));
    	t[*taille]=val;
    	(*taille)++;
    	return t;
    }
     
    void modifier(int *t, int taille) {
    	if (taille == 0) {
    		printf("tableau est vide!\n");
    		return;
    	}
     
    	int val;
    	printf("donner la valeur a modifier: ");
    	scanf("%d", &val);
     
    	int pos;
    	pos=chercheVal(t, taille, val);
    	if (pos == -1) {
    		printf("valeur n'existe pas!\n");
    		return;
    	}
     
    	printf("donner la nouvelle valeur: ");
    	scanf("%d", &t[pos]);
    }
     
    int *supprimer(int *t, int *taille) {
    	if (*taille == 0) {
    		printf("le tableau est vide!\n");
    		return t;
    	}
     
    	int val;
    	printf("donner la valeur a supprimer: ");
    	scanf("%d", &val);
     
    	int pos;
    	pos=chercheVal(t, *taille, val);
    	if (pos == -1) {
    		printf("l'element n'existe pas!\n ");
    		return t;
    	}
     
    	for (int i=pos+1; i < (*taille); i++)
    		t[i-1]=t[i];
     
    	(*taille)--;
    	return realloc(t, sizeof(int)*(*taille));
    }
     
    void lister(int *t, int taille) {
    	if (taille == 0) {
    		printf("le tableau est vide!\n");
    		return;
    	}
    	for (int i=0; i < taille; i++)
    		printf("t[%d]=%d  ", i, t[i]);
    	printf("\n");
    }
     
    int main() {
    	int *t=NULL; int taille=0; int choix;
    	do {
    		system("cls");
    		choix=menu();
    		switch(choix) {
    			case 0:
    				printf("fin du programme!\n");
    				break;
    			case 1:
    				t=ajouterval(t, &taille);
    				break;
    			case 2:
    				modifier(t, taille);
    				break;
    			case 3:
    				t=supprimer(t, &taille);
    				break;
    			case 4:
    				lister(t, taille);
    				break;
    		}
    		system("pause");
    	} while (choix != 0);
    	return 0;
    }
    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

  11. #11
    Candidat au Club
    merci beaucoup pour votre aide

###raw>template_hook.ano_emploi###