Problème Langage C Structure, Pointeur, ...
Répondre à la discussion
Affichage des résultats 1 à 18 sur 18

Problème Langage C Structure, Pointeur, ...



  1. #1
    invite3e43df7f

    Question Problème Langage C Structure, Pointeur, ...


    ------

    Bonjour a tous.

    Voila, je rencontre quelaues petits preoblemes en langage C (je tiens à dire que je suis débutant ).

    Le but est de creer des fiches afin de creer une listes les contenant.

    Il faut ensuite afficher ce que l on a entre dans chaque fiche, puis afficher enfin le nombre de fiches composant la liste. La est mon petit probleme.

    Voici mon code source :



    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #define LGTXT 256



    typedef struct Fiche
    {
    char Nom[256];
    struct Fiche * Suivante;
    }fiche;

    typedef struct Dossier{
    struct Fiche * debut;
    struct Fiche * fin;
    }dossier;

    typedef struct Liste{
    void * debut;
    void * fin;
    }liste;



    Fiche*CreerFiche(char Texte[] )
    {
    fiche* ptrfiche=(fiche*)malloc(sizeof (fiche));
    if(ptrfiche!=NULL)
    {
    strcpy(ptrfiche->Nom,Texte);
    ptrfiche->Suivante=NULL;
    }
    else
    {
    printf("Memoire pleine");
    }
    return ptrfiche ;
    }



    int main()
    {
    int arret;
    char reponse[256];
    fiche* ptrnouveau;
    fiche* ptrdebut;
    int nombre;

    arret = 1;
    ptrdebut = NULL;
    ptrnouveau = NULL;
    nombre = 0;

    do{
    printf("Entrer le nom de la fiche.\n\nEntrer ''Fin'' pour terminer le programme.\n\n");
    gets (reponse);
    printf("\n\n\n");
    if (strcmp(reponse,"Fin"))
    {
    ptrnouveau = CreerFiche(reponse);
    ptrnouveau->Suivante = ptrdebut;
    ptrdebut = ptrnouveau;
    nombre++;
    }
    else arret=0;
    }while(arret);

    if(nombre>1) printf("Vous avez cree %d fiches.",nombre);
    else printf("Vous avez cree %d fiche.",nombre);

    getchar();
    }



    Voilà, par contre, je n'ai pas réussi à faire en sorte que le programme m'affiche ce que j'ai entré.

    En fait, je vais donner un exemple de ce que je voudrais

    J'entre le nom de la première fiche : aaa

    J'entre le nom de la deuxième fiche : bbb

    ...

    J'entre le nom de la n-ième fiche : xxx

    J'entre "Fin"

    Le programme m'affiche alors :

    Vous avez entré n fiches.

    Nom de la fiche 1 : aaa

    Nom de la fiche 2 : bbb

    ...

    Nom de la fiche n : xxx



    Voilà voilà

    Quelqu'un pourrait-il m'aider à obtenir ce que je voudrais SVP ?

    En vous remerciant.

    -----

  2. #2
    invite3d7be5ae

    Re : Problème Langage C Structure, Pointeur, ...

    Si tu veux le faire en C++ tu peux utiliser des tableaux en mémoire dynamique?
    A chaque fois, tu créés un nouveau tableau de taille n+1, tu copies toutes tes données et tu détruis l'autre tableau de taille n.
    A utiliser : new ... [...] et delete[] ...

    Pour ton programme, dans la déclaration de "CreerFiche" mettre fiche* et non Fiche* : cela génére une erreur de compilation.
    Après, ça marche.
    Pour l'affichage, tu stockes à l'envers tes chaînes de caractère.
    Utilise un pointeur ptrfin pour stocker la denière chaîne de caractère.
    N'oublie pas de libérer la mémoire à la fin du programme.

    Pole.

  3. #3
    invite597d4991

    Re : Problème Langage C Structure, Pointeur, ...

    Pas besoin de C++ pour faire des tableaux dynamiques, et SUTOUT pas besoin de copier les données à chaque fois que l'on rajoute un élément.On peut utiliser realloc, ou mieux une liste liée...


    Ce qu'il faut faire pour afficher: (pseudocode)
    Code:
    int affiche_liste(Fiche *premièrefiche)
    {
    printf(premièrefiche->data);
    
    while(premièrefiche->fichesuivante) \* je suppose que les ptr st à NULL si la liste est finie... et que NULL==0*\
    {
     premièrefiche = premièrefiche->fichesuivante;
     printf(premièrefiche->data);
    }
    Vala, reste plus qu'à virer ce do while et à le remplacer par un for( ;; ) avec appel à une procédure de sortie qui affiche le truc en passant.

  4. #4
    invite597d4991

    Re : Problème Langage C Structure, Pointeur, ...

    Ah aussi j'ajoutes non rien.

  5. A voir en vidéo sur Futura
  6. #5
    invite3e43df7f

    Re : Problème Langage C Structure, Pointeur, ...

    Merci

    Je vais travaillé sur ce que vous m'avez tout les deux répondu et reposterais ici si je rencontre à nouveau des problèmes

    Merci encore.

    PS : je suis un gros débutant en C, alors en ce qui concerne le C++, je ne suis même pas un quark

  7. #6
    invite3d7be5ae

    Re : Problème Langage C Structure, Pointeur, ...

    Citation Envoyé par overmind
    Pas besoin de C++ pour faire des tableaux dynamiques, et SUTOUT pas besoin de copier les données à chaque fois que l'on rajoute un élément.On peut utiliser realloc, ou mieux une liste liée...
    Exact, mais c'est beaucoup, beaucoup plus simple en C++.

    N'oublie surtout pas les free dans la boucle d'affichage.
    (Je me répète, mais c'est très important )

    Citation Envoyé par overmind
    Vala, reste plus qu'à virer ce do while et à le remplacer par un for( ;; ) avec appel à une procédure de sortie qui affiche le truc en passant.
    Moi, je ferais plutôt un break (peut-être que ça n'existe pas en C, je ne sais pas ) Et en dehors de la boucle, j'afficherai.

    Après, chacun ses goûts.

    Pole.

  8. #7
    invite3e43df7f

    Re : Problème Langage C Structure, Pointeur, ...

    Bon bon bon, après avoir essayé plusieurs fois et différemment, je n'ai pas réussi à faire fonctionner mon programme correctement (avec ce que Overmind m'a proposé comme code pour l'affichage). Je ne vois vraiment pas où l'intégrer dans mon code source.

    Aussi, je n'ai pas compris pourquoi transformer mon do while en for, et dans ce cas là, comment faudrait-il faire ?

    Quant-aux free, c'est où exactement que je dois le remplacer à la place de printf ? Et comment ça se fait qu'avec cette fonction, de la mémoire est vidée ? Et si je vidais le buffer entre temps, avec fflush (stdin.h), est-ce que ça aurait le même effet ?

    Merci de votre aide

  9. #8
    invite597d4991

    Re : Problème Langage C Structure, Pointeur, ...

    Citation Envoyé par Pole
    Moi, je ferais plutôt un break (peut-être que ça n'existe pas en C, je ne sais pas ) Et en dehors de la boucle, j'afficherai.

    Après, chacun ses goûts.

    Pole.
    En fait ici pas besoin de break puisque sortir de la boucle revient à sortir du programme. Sinon c'est effectivement la meilleure solution, plus élégante qu'une variable qu'on teste à chaque fois.

    Pour l'intégration de cette fonction, il faudrait que tu voie ce qui se passe dans ta tête. Tu as créé un liste liée, à peu de choses près. Essaye de faire ça plus proprement, ie avec une structure liste (utilisée cette fois...) et un jeu de fonctions qui l'exploitent à fond.

    Du bricolage sur les pointeurs tel que tu le fait dans main n'est pas acceptable pour un programme plus important, il faudreait faire ça dans une procédure à coté. Il va te faloir une procédure pour créer une liste, une autre pour la détruire, une procédure que tu peux appeler push par exemple, qui fait en gros ce qu'il y a dans ta boucle, et enfin une dernière qui affiche le tout.
    On peut ajouter une procédure qui rapatrie les données, et une dernière qui teste la chaine de retour pour savoir si c'est fin ou pas:
    Code:
    /*je ne détaille pas: */
    char * get_result(void);
    int affiche_et_sort(List * liste); // affichage, libération
    int push(char * name, List *liste ); /* a toi de voir dans quel ordre tu veux pusher... */
    int test_string(char * result);
    List * create_list();
    
    int main()
    {
    //déclarations...
    for ( ;; )
    {
    result = get_result();
    if (test_string(result)) affiche_et_sort(liste);
    push(result);
    }
    }
    C'est tout de même plus clair.


    Des éléments de réponse pour certaines fonctions:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define DEBUG
    void * malloc_(int size)
    {
    #ifdef DEBUG
    	fprintf(stdout,"Une allocation mémoire, taille %d\n",size);
    #endif
    	void * retval;
    	retval = malloc(size);
    	if (retval == NULL)
    	{
    		fprintf(stderr,"Memoire insuffisante.\n");
    		exit(EXIT_FAILURE);
    	}
    	return retval;
    }
    
    struct char_Node
    {
    	char *data;
    	struct char_Node *next;
    	struct char_Node *previous;
    };
    
    typedef struct char_Node Char_Node;
    
    
    struct char_List
    {
    	Char_Node *head;
    	Char_Node *queue;
    	int size;
    };
    
    typedef struct char_List Char_List;
    
    Char_List *mk_char_list()
    {
    	Char_List * list = malloc_(sizeof(Char_List));
    	return list;
    }
    
    int append_char_to_list(const char c,Char_List * liste)
    {
    	int counter = 1;
    	Char_Node *curnode = NULL;
    	Char_Node *new_node = (Char_Node *) malloc_(sizeof(Char_Node));
    	new_node->data = (char *) malloc_(sizeof(char));
    	*(new_node->data)= c;
    #ifdef DEBUG
    	printf("Nouvelle node créée, valeur %c\n",*(new_node ->data));
    #endif
    	new_node->next = NULL;
    	new_node->previous = NULL;
    
    	if (!(liste->head))
    	{
    #ifdef DEBUG
    		printf("Append head\n");
    #endif
    		liste->head = new_node;
    		liste->queue = new_node;
    		liste->size = 1;
    		return 1;
    	}
    
    	curnode = liste->head;
    	
    	while (curnode->next)
    	{
    		if (counter > liste->size) return ERR;
    		curnode = curnode->next;
    		++counter;
    	}
    
    	curnode->next = new_node;
    	new_node->previous = curnode;
    	liste->queue = new_node;
    	(liste->size)++;
    	
    	return 1;
    }
    	
    
    int insert_char_to_list(const char c, Char_List * list, const int pos)
    {
    	if ((pos > list->size)||(pos<=0)) return ERR;
    	
    	Char_Node * new_node = (Char_Node *) malloc_(sizeof(Char_Node));
    	new_node->next = NULL;
    	new_node->previous = NULL;
    	new_node->data = (char *) malloc_(sizeof(char));
    	
    	if (pos == 0)
    	{
    		Char_Node *head = list->head;
    		list->head = new_node;
    		head->previous = new_node;
    		new_node->next = head;
    		list->size ++;
    		return 1;
    	}
    	
    	if (pos == list->size)
    	{
    		Char_Node * queue = list->queue;
    		list->queue = new_node;
    		new_node->previous = queue;
    		queue->next = new_node;
    		(list->size) ++; 
    	}		
    	int counter = 1;
    	Char_Node *curnode = list->head;
    
    	while (counter < pos)
    	{
    		if (!(curnode->next)) return ERR;
    		curnode = curnode->next;
    		++counter;
    	}
    	
    	Char_Node * Previous = curnode->previous;
    	curnode->previous = new_node;
    	new_node->previous = Previous;
    	new_node->next = curnode;
    	++(list -> size);
    	return 1;
    }
    
    int destroy_char_list(Char_List **list)
    {
    #ifdef DEBUG
    	printf("Entrée dans le destructeur de liste\n");
    #endif
    	if (!(*list)->head)
    	{
    		free(*list);
    		return 1;
    	}
    	Char_Node *head = (*list)->head;
    	Char_Node *curnode = head;
    	Char_Node *next;
    
    	while (curnode->next)
    	{
    		next = curnode->next;
    		free( curnode);
    		curnode = next;
    	}
    	free((*list)->queue);
    	free(*list);
    	*list = NULL;
    	return 1;
    }

  10. #9
    invite3e43df7f

    Re : Problème Langage C Structure, Pointeur, ...

    Gnié

    Une question, comment vous faites pour sortir un truc balèze comme ça en si peu de temps ? Vous programmez depuis la plus tendre enfance ?

    Et bien, je vais en avoir du travail mais tant mieux, je vais essayer d'apprendre en lisant ce que vous avez fait, mais demain, car là, je suis exténué, et en ai un peu marre du C pour tout avouer (rester dessus tout un après midi pour essayer de faire un petit programme enfentin sans y arriver ... m'enfin voilà ).

    Donc je vais étudier cela en détail et vous poserais des questions préparées si j'en ai

    Par contre, j'ai copié collé votre programme du bas dans Visual Studio juste par curiosité pour voir ce que ça donnait, mais surviennent quelques petites erreurs.

    Déjà quant-au ERR, il me dit qu'il ne connait pas, et moi non plus d'ailleurs enfin j'ai remplacé ça par 0 (donc return 0; ) pour que ça marche, mais je n'avais pas vu qu'il me signalait autre chose :

    Char_List *mk_char_list()
    {
    char_List * list = malloc_(sizeof(Char_List));
    return list;
    }


    ligne 41

    Il me dit : 'initializing' : cannot convert from 'void*' to 'char_List*'.

    Qu'est-ce que ça veut dire exactement ? Ca veut dire qu'on ne peut pas pointer un élément de type void sur une structure ?

    Euh, bah voilà, merci encore de votre disponibilité et de vos réponses

    Bonne soirée (nuit ?)

  11. #10
    invite6de5f0ac

    Re : Problème Langage C Structure, Pointeur, ...

    Bonsoir,

    Non mais je rêve... un break pour arrêter une boucle? et un for? La base pour une liste simplement chaînée est un while (et pas un do...while), because la liste vide), avec un itérateur du genre:

    while (list) { print (list_element) ; list->next() ; }

    avec une sentinelle pour la liste vide... vous êtes tous intoxiqués au Java, ou vous connaissez un peu les pointeurs en C?

    (désolé, je suis un peu sec en apparence, mais c'est juste pour dire que des fois il vaut mieux revenir aux basiques.... )

    -- françois

  12. #11
    invite597d4991

    Re : Problème Langage C Structure, Pointeur, ...

    Citation Envoyé par L'Etudiant
    Gnié

    Une question, comment vous faites pour sortir un truc balèze comme ça en si peu de temps ? Vous programmez depuis la plus tendre enfance ?

    Et bien, je vais en avoir du travail mais tant mieux, je vais essayer d'apprendre en lisant ce que vous avez fait, mais demain, car là, je suis exténué, et en ai un peu marre du C pour tout avouer (rester dessus tout un après midi pour essayer de faire un petit programme enfentin sans y arriver ... m'enfin voilà ).

    Donc je vais étudier cela en détail et vous poserais des questions préparées si j'en ai

    Par contre, j'ai copié collé votre programme du bas dans Visual Studio juste par curiosité pour voir ce que ça donnait, mais surviennent quelques petites erreurs.

    Déjà quant-au ERR, il me dit qu'il ne connait pas, et moi non plus d'ailleurs enfin j'ai remplacé ça par 0 (donc return 0; ) pour que ça marche, mais je n'avais pas vu qu'il me signalait autre chose :

    Char_List *mk_char_list()
    {
    char_List * list = malloc_(sizeof(Char_List));
    return list;
    }


    ligne 41

    Il me dit : 'initializing' : cannot convert from 'void*' to 'char_List*'.

    Qu'est-ce que ça veut dire exactement ? Ca veut dire qu'on ne peut pas pointer un élément de type void sur une structure ?

    Euh, bah voilà, merci encore de votre disponibilité et de vos réponses

    Bonne soirée (nuit ?)

    Il faut faire du transtypage, normalement la conversion de *void vers *cequetuveux est implicite, sauf si tu as un compilo C++, ou un vieux truc.
    Pour ERR, rajoutes
    #define ERR (-1)



    Non mais je rêve... un break pour arrêter une boucle? et un for? La base pour une liste simplement chaînée est un while (et pas un do...while), because la liste vide), avec un itérateur du genre:

    while (list) { print (list_element) ; list->next() ; }
    A part des considérations religieuses, il n'y a pas de différence entre for (;; ) et while (1), Quand au break, pour sortir d'une boucle infinie, il n'y a pas 92 choix possibles (tu préfères goto?).

    Après, le do.. while, pourquoi pas, ça ne me gêne pas personellement (du moment que c'est lisible).

    Tout cela dépend de l'implémentation de ta liste.

    Ensuite:
    while (list) { print (list_element) ; list->next() ; }

    On est en C ici... alors list->next()...
    Ensuite tu remarquera que la même chose est écrit dans mon code plus haut, mais en C...

  13. #12
    invite6de5f0ac

    Re : Problème Langage C Structure, Pointeur, ...

    Citation Envoyé par overmind
    A part des considérations religieuses, il n'y a pas de différence entre for (;; ) et while (1), Quand au break, pour sortir d'une boucle infinie, il n'y a pas 92 choix possibles (tu préfères goto?).
    Bonjour,

    D'accord, quoique moi j'écris plutôt while (true) pour une boucle infinie, question de goût... Mais je crois que true c'est déjà du C++? ça fait un bail que je n'ai pas écrit de C "standard".

    Mon problème c'est que la boucle n'a aucune raison d'être infinie. On doit pouvoir déterminer à quel moment on a atteint la fin de la liste. Récursivement, on s'arrête quand la liste restante est vide (d'où mon exemple). Et c'est aussi la raison pour laquelle on place une sentinelle.

    Après, le do.. while, pourquoi pas, ça ne me gêne pas personellement (du moment que c'est lisible).
    Là, pas d'accord. Le do...while est toujours exécuté au moins une fois, et donc est inapproprié si la liste est vide. À moins de placer un test en début de do...while, ce qui revient à le transformer en while.

    Tout cela dépend de l'implémentation de ta liste.

    Ensuite:
    while (list) { print (list_element) ; list->next() ; }

    On est en C ici... alors list->next()...
    Ensuite tu remarquera que la même chose est écrit dans mon code plus haut, mais en C...
    Voui. Comme je disais, je n'ai pas touché au C pur et dur depuis un moment... Et encore, je n'ai pas utilisé la STL de C++, qui résoudrait tous les problèmes...

    -- françois

  14. #13
    invite3d7be5ae

    Re : Problème Langage C Structure, Pointeur, ...

    Citation Envoyé par fderwelt
    D'accord, quoique moi j'écris plutôt while (true) pour une boucle infinie, question de goût... Mais je crois que true c'est déjà du C++? ça fait un bail que je n'ai pas écrit de C "standard".
    Effectivement, true est du C++. Mais il peut être remplacé par 1. Et on obtient
    while(1).
    Citation Envoyé par fderwelt
    Mon problème c'est que la boucle n'a aucune raison d'être infinie. On doit pouvoir déterminer à quel moment on a atteint la fin de la liste. Récursivement, on s'arrête quand la liste restante est vide (d'où mon exemple). Et c'est aussi la raison pour laquelle on place une sentinelle.


    Là, pas d'accord. Le do...while est toujours exécuté au moins une fois, et donc est inapproprié si la liste est vide. À moins de placer un test en début de do...while, ce qui revient à le transformer en while.
    C'est l'utilisateur qui remplit la liste. Et s'il n'a pas infiniment de temps, et un ordinateur avec infiniment de mémoire,.............. il ne peut pas rentrer une liste infinie.

    Je pense que l'on ne doit pas parler de la même chose. J'ai l'impression que tu parles de l'affichage et moi et overmind de l'entrée des chaînes. Je me trompe?
    Dans ce cas là, pas besoin de boucle infinie.

    Pole.

  15. #14
    invite597d4991

    Re : Problème Langage C Structure, Pointeur, ...

    Oui, en fait le problème c'est que l'interface utilisateur (ou une boucle infinie est justifiée) et l'implémentation de la liste sont mélangées dans le programme originel, d'où à mon avis un mal entendu... (qui concerne aussi le do..while)

  16. #15
    invite6de5f0ac

    Re : Problème Langage C Structure, Pointeur, ...

    Citation Envoyé par overmind
    Oui, en fait le problème c'est que l'interface utilisateur (ou une boucle infinie est justifiée) et l'implémentation de la liste sont mélangées dans le programme originel, d'où à mon avis un mal entendu... (qui concerne aussi le do..while)
    Bonjour,

    C'est exactement ça. Tant que c'est l'utilisateur qui a la main, la boucle est (potentiellement) infinie. Ensuite, c'est "Mr Computer says", donc une boucle finie. Désolé pour le malentendu.

    -- françois

  17. #16
    invite97a92052

    Re : Problème Langage C Structure, Pointeur, ...

    Citation Envoyé par Pole
    Effectivement, true est du C++. Mais il peut être remplacé par 1. Et on obtient
    while(1)

    Hello,

    Juste au passage, le type bool fait partie du C standard depuis 7 ans ("vieux" compilos s'abstenir) !
    ( #include <stdbool.h> )

  18. #17
    invite3e43df7f

    Re : Problème Langage C Structure, Pointeur, ...

    Merci de votre aide.

    Je vais travailler dessus quand j'aurais un peu plus de temps, car j'entre dans les semaines de partiels

    Pour ce qu'a dit Overmind :
    Il faut faire du transtypage, normalement la conversion de *void vers *cequetuveux est implicite, sauf si tu as un compilo C++, ou un vieux truc.
    D'accord, mais je ne sais toujours pas quoi faire

    Pour information, mon compilateur est Microsoft Visual Studio 2003.

    Bonne soirée

  19. #18
    invite3d7be5ae

    Re : Problème Langage C Structure, Pointeur, ...

    Citation Envoyé par L'Etudiant
    Pour ce qu'a dit Overmind :
    Citation Envoyé par overmind
    Il faut faire du transtypage, normalement la conversion de *void vers *cequetuveux est implicite, sauf si tu as un compilo C++, ou un vieux truc.
    D'accord, mais je ne sais toujours pas quoi faire
    Tu écris (cequetuveux*) juste après le signe égal.
    Exemple : new_node->data = (char *) malloc_(sizeof(char)); convertit le void* qui est retourné par malloc en char*.
    De manière générale, (type_cequetuveux) A transforme (transtype) A en type_cequetuveux. Tu peux faire ça avec des pointeurs, des entiers, des réels,...

    Bonne chance.

    Pole.

Discussions similaires

  1. problème avec langage C++
    Par invite0f6e0be6 dans le forum Logiciel - Software - Open Source
    Réponses: 5
    Dernier message: 03/10/2007, 12h20
  2. Petit problème en langage C. Please Help!
    Par invite00a39544 dans le forum Électronique
    Réponses: 4
    Dernier message: 25/03/2007, 18h33
  3. Langage C : pointeur sur une fonction en argument ...
    Par invite1a99f682 dans le forum Logiciel - Software - Open Source
    Réponses: 1
    Dernier message: 27/07/2005, 11h29
  4. Problème en langage VBA
    Par invite588da7a7 dans le forum Logiciel - Software - Open Source
    Réponses: 2
    Dernier message: 09/07/2004, 14h00
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...