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 :

tableau de structures, type booleen, gestion de chaînes


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

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

    Informations forums :
    Inscription : Février 2008
    Messages : 207
    Par défaut tableau de structures, type booleen, gestion de chaînes
    Bonjour,

    apprenant le C après 2 ans de java, je me retrouve bloqué face à certaines choses que l'on ne peut faire de la même manière.

    On me demande quelque chose de très simple: créer un type matériel pour représenter un matériel informatique (avec son numéro de série, sa nature, son année d'achat et son état de fonctionnement) puis créer un stock (donc un tableau) de plusieurs matériaux informatiques.

    En faisant une recherche d'un numéro de série, je dois savoir s'il est dans la base de données en retournant son indice ou -1 s'il n'y est pas.

    En java, rien de plus simple, j'ai écrit ceci:

    Code JAVA : 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
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
     
    class Materiel {
    	int numSerie;
    	String nature;
    	int anneeAchat;
    	String etat;
     
    	static Materiel dataReceive() throws NumberFormatException, IOException
    	{
    		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    		Materiel res = new Materiel();
    		System.out.println("Numéro de série?");
    		res.numSerie = Integer.parseInt(in.readLine());
    		System.out.println("Nature?");
    		res.nature = in.readLine();
    		System.out.println("Année d'achat?");
    		res.anneeAchat = Integer.parseInt(in.readLine());
    		System.out.println("état de fonctionnement?");
    		res.etat = in.readLine();
    		return res;
    	}
     
    	void dataDisplay()
    	{
    		System.out.println("Numéro de série:" + this.numSerie);
    		System.out.println("Nature:" + this.nature);
    		System.out.println("Année d'achat:" + this.anneeAchat);
    		System.out.println("Etat de fonctionnement:" + this.etat);
    		System.out.println();
    	}
    }
    class Stock {
    	Materiel [] tabMat = new Materiel[100];
    	int nbMat = 0;
     
    	void ajouter(Materiel m)
    	{
    		this.tabMat[this.nbMat] = m;
    		this.nbMat++;
    	}
     
    	void affichage()
    	{
    		for (int i = 0; i < nbMat; i++)
    		{
    			this.tabMat[i].dataDisplay();
    		}
    	}
     
    	boolean disponibilite(int numSerie){
    		for (int i = 0; i < nbMat; i++){
    			if (tabMat[i].numSerie == numSerie) return true;
    		}
    		return false;
    	}
     
    	int getNumSerie() throws NumberFormatException, IOException{
    		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    		System.out.println("Tapez le numéro de série du produit recherché: ");
    		int numSerie = Integer.parseInt(in.readLine());
    		return numSerie;
    	}
     
    	void appelDisponibilite(int numSerie){
    		if (disponibilite(numSerie)) System.out.println("Le produit est disponible");
    		else System.out.println("Le produit est indisponible");
    	}
    }
    public class StockInfo {
    	public static void main(String [] args) throws NumberFormatException, IOException
    	{
    		char reponse = 'n';
    		Stock s = new Stock();
    		do
    		{
    			BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    			s.ajouter(Materiel.dataReceive());
    			System.out.println("Voulez-vous rentrer un autre produit?");
    			reponse = in.readLine().charAt(0);
    			System.out.println();
    		} while (reponse != 'n');
    		s.affichage();
    		s.appelDisponibilite(s.getNumSerie());
    	}
    }

    En C, hum hum... j'ai quelques soucis! Ma fonction de recherche du numéro de série ne fonctionne pas (le programme plante) et, second problème, quand je tape, dans la nature du matériel, "carte mère", par exemple, le compilateur enregistre carte pour la "nature" et "mère" pour l'état de fonctionnement, laissant l'année d'achat à 0.

    Par contre, si je tape un seul mot, tout fonctionne sauf pour la recherche du numéro de série.

    Pourriez-vous m'aider, s'il vous plait?

    Je vous donne mon 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
    #include <stdio.h>
    #include <stdlib.h>
    #define NP 100
     
    struct materiel {
        int num_serie;
        char nature[40];
        int annee_achat;
        char etat[40];
    };
     
    void display(struct materiel stock [], int nb_mat){
     
        int i;
        for (i = 0; i < nb_mat; i++){
            printf("Numéro de série: %d\n", stock[i].num_serie);
            printf("Nature du matériel: %s\n", stock[i].nature);
            printf("Année d'achat: %d\n", stock[i].annee_achat);
            printf("Etat de fonctionnement: %s\n", stock[i].etat);
        }
        }
     
    void dataReceive(struct materiel stock [], int nb_mat){
        int i;
        for (i=0; i<nb_mat; i++){
            printf("Numéro de série?\n");
            scanf("%d", &stock[i].num_serie);
            printf("Nature du matériel?\n");
            scanf("%s", &stock[i].nature);
            printf("Année d'achat?\n");
            scanf("%d", &stock[i].annee_achat);
            printf("En état de fonctionnement?\n");
            scanf("%s", &stock[i].etat);
            }
    }
     
    int get_nb_mat(){
        int nb_mat;
        printf("Combien de produits voulez-vous rentrer?\n");
        scanf("%d", &nb_mat);
        return nb_mat;
        }
     
    int disponibilite(struct materiel stock [], int num_serie, int nb_mat){
        int i;
        for (i = 0; i < nb_mat; i++){
            if (stock[i].num_serie == num_serie){
                printf("Le numéro de série recherché se trouve à l'indice %d\n", i);
                return i;}
        }
        return -1;
    }
     
    int get_num_serie(){
        int num_serie;
        printf("Tapez le numéro de série du produit recherché:\n");
        scanf("%d", num_serie);
        return num_serie;
    	}
     
    int main()
    {
        struct materiel stock [NP];
        void display(struct materiel stock [], int nb_mat);
        void dataReceive(stock, nb_mat);
        int disponibilite(stock, num_serie, nb_mat);
        void appel_disponibilite(stock, num_serie, nb_mat);
        int get_nb_mat();
        int nb_mat;
        int num_serie;
     
        nb_mat = get_nb_mat();
        dataReceive(stock, nb_mat);
        display(stock, nb_mat);
     
        num_serie = get_num_serie();
        disponibilite(stock, num_serie, nb_mat);
    }
    Merci par avance,
    Johnny3

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

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    quand je tape, dans la nature du matériel, "carte mère", par exemple, le compilateur enregistre carte pour la "nature" et "mère" pour l'état de fonctionnement, laissant l'année d'achat à 0.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            scanf("%s", &stock[i].nature);
    scanf, avec pour format "%s" lit une chaîne de caractères, mais la chaîne est considéré terminée avec le premier caractère "blanc" (ou équivalent) trouvé. Il ne lit pas nécessairement une ligne complète.

    Utilises plutôt pour cela la fonction fgets() (n'utilises PAS gets()) sur l'entrée standard stdin). Elle permet :

    - de lire une ligne complète comme une chaîne de caractères si le buffer de réception est assez grand pour la contenir

    - de limiter le nombre de caractères, ce qui permet de ne pas dépasser la taille du buffer de réception (ce que ne fait pas gets() ce qui conduit à éviter son utilisation).

    - par contre, elle place dans la chaîne le caractère de fin de ligne ('\n') si le buffer était suffisamment grand pour stocker toute la ligne. Ce peut être gênant et dans ce cas, il faut le supprimer : chercher sa position avec strchr() et le remplacer par '\0'. (gets() ne le fait pas, mais cet "avantage" ne compense pas l'inconvénient évoqué précédemment)

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

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Remarques complémentaires sur ton code :

    - Place les prototypes des fonctions en tête du fichier plutôt que dans le main() : les fonctions peuvent être utilisées par d'autres fonctions que main()
    int get_nb_mat(); n'est pas un prototype. Ecrire : int get_nb_mat(void);

    - void display(....) n'a pas à avoir return quelque chose mais return tout court (ou rien si on sort de la fonction sur son } terminal)

    - int disponibilite(....) renvoie une valeur à sémantique booléenne (Vrai/Faux). Utilise plutôt comme valeur de retour 1 (pour vrai) et 0 (pour faux). Ceci permet d'utiliser le retour comme un booléen (ce qu'il est) et d'écrire, par exemple
    if(disponibilité(....)) printf("Disponible");

    - Tu es obligé de transmettre à chaque fois le tableau et le nombre de ses éléments. Ceci parce que tu n'as pas créé un type pour décrire ta collection. Il semble logique d'en faire un. 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
    typedef struct
    {
      struct materiel stock [NP];
      int  nb_mat;
    } TStock;
     
    int main()
    {
        TStock stock;
        stock.nb_mat = get_nb_mat();
        dataReceive(&stock);
    ....
     
     
    void dataReceive(TStock *stock){
        int i;
        for (i=0; i<stock->nb_mat; i++){
            printf("Numéro de série?\n");
            scanf("%d", &stock->stock[i].num_serie);
    ....

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

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

    Informations forums :
    Inscription : Février 2008
    Messages : 207
    Par défaut
    merci pour tout cela.

    J'ai essayé d'appliquer tes conseils, mais à la fin, le programme m'indiquait 17 erreurs! Je m'y suis un peu perdu.

    Je vais essayer de reprendre les choses point par point pour construire le programme, en l'allégeant pour ne prendre en compte qu'un ou deux éléments à chaque fois.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <stdio.h>
    #include <stdlib.h>
    #define NP 100
     
    struct materiel {
        int num_serie;
        char nature[40];
    };
     
    typedef struct
    {
      struct materiel stock [NP];
      int  nb_mat;
    } TStock;
    Jusque là, je pense que c'est bon.

    Ensuite:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void dataReceive(TStock *stock){
        int i;
        for (i=0; i<stock->nb_mat; i++){
            printf("Numéro de série?\n");
            scanf("%d", &stock->stock[i].num_serie);
            printf("Nature du matériel?\n");
            scanf("%s", &stock->stock[i].nature);
            }
    }
    Puis le main, et là, ça se complique:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main(void)
    {
     
        TStock stock;
        stock.nb_mat = get_nb_mat();
        dataReceive(&stock);
        return 0;
    }
    soit, le programme complet:

    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
    #include <stdio.h>
    #include <stdlib.h>
    #define NP 100
     
    struct materiel {
        int num_serie;
        char nature[40];
    };
     
    typedef struct
    {
      struct materiel stock [NP];
      int  nb_mat;
    } TStock;
     
    void dataReceive(TStock *stock);
    int get_nb_mat();
     
     
    void dataReceive(TStock *stock){
        int i;
        for (i=0; i<stock->nb_mat; i++){
            printf("Numéro de série?\n");
            scanf("%d", &stock->stock[i].num_serie);
            printf("Nature du matériel?\n");
            gets(stock->stock[i].nature);
            }
    }
     
    int get_nb_mat(){
        int nb_mat;
        printf("Combien de produits voulez-vous rentrer?\n");
        scanf("%d", &nb_mat);
        return nb_mat;
        }
     
     
    int main(void)
    {
        TStock stock;
        stock.nb_mat = get_nb_mat();
        dataReceive(&stock);
        return 0;
    }
    Alors, ça semble fonctionner, mais nb_mat n'est pas pris en compte.

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

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    mais à la fin, le programme m'indiquait 17 erreurs!
    Ce n'est rien! Souvent, la première erreur en engendre d'autres ensuite. Il faut corriger les erreurs dans l'ordre d'apparition et recompiler
    Alors, ça semble fonctionner, mais nb_mat n'est pas pris en compte.
    Ton problème est sur l'emploi de scanf() suivi de gets() dans dataReceive()

    Les entrées clavier sont délicates à manier.

    Il faut savoir qu'avec scanf()
    - que les caractères "blanc" qui précèdent la donnée sont sautés
    - que le caractère qui suit la fin de lecture de la donnée est toujours en attente de lecture.
    Alors qu'avec fgets() la ligne entière est lue, y compris le caractère de fin de ligne (qui termine la lecture).

    Mélanger les deux pose alors problème. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     scanf("%d",&i);
     fgets(tab1,.....,stdin);
    la lecture de i laisse le '\n' en attente. Du coup, le fgets() le trouve et lit tout de suite une ligne composée du seul '\n'
    Par contre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     scanf("%d",&i);
     scanf("%s",tab1);
    ne présentera pas cet inconvénient, mais une entrée "aze rty" donnera "aze" dans tab1, et laisse en attente "rty".

    On peut envisager une solution à base de fgets(), sans scanf() :
    -Lire une ligne dans un tableau,
    Les "blancs" qui précèdent la chaîne sont conservés ainsi que ceux qui précèdent le '\n' sont conservés et le '\n'
    - éliminer le '\n' (et les blancs qui le précèdent si ils peuvent être gênant lors de l'acquisition d'une chaîne)
    - Si on veut lire une valeur, appliquer à ce tableau la fonction sscanf() (comme scanf(), mais l'entrée à analyser est dans un tableau)

    Ou une solution à base uniquement de scanf, mais en prenant soin de lire toute la ligne.
    Les formats sont un peu plus complexes :

    Exemple : lecture d'un entier en début de ligne. Le reste de la ligne (y compris '\n') sera lu et ignoré
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     scanf("%d%*[^\n]%*c",&i);
    Le %d lit l'entier (en sautant les caractères "blanc" qui le précèdent)
    le %*[^\n] lit tous les caractères jusquà trouver '\n et les ignore (à cause de *)
    le %*c lit le '\n' et l'ignore.

    Exemple : lecture d'une ligne en sautant les "blancs" qui précèdent la chaine utile si il y en a
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     scanf("%*[ ]%[^\n]%*c",tab1);
    A noter que les blancs qui précèdent la fin de la ligne, si il y en a, sont inclus dans tab1 (mais pas le '\n') et, si ils sont gênant, il faut les éliminer.

  6. #6
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

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

    Informations forums :
    Inscription : Février 2008
    Messages : 207
    Par défaut
    bonsoir,

    je me sens débordé en ce moment par les autres UEs du Cnam (notamment réseaux et systèmes d'information) et je ne pourrai malheureusement pas revenir sur ce programme ce we, mais je le retravaillerai normalement la semaine prochaine (plutôt le we)

    Merci déjà pour l'aide apportée.

    Johnny

Discussions similaires

  1. tableau de structure(variable Type) traiter les éléments
    Par Patnel dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 18/04/2014, 08h48
  2. Réponses: 3
    Dernier message: 03/04/2013, 10h41
  3. Réponses: 4
    Dernier message: 19/11/2011, 20h53
  4. [WINDEV11] Gestion de tableau de structure
    Par shensi dans le forum WinDev
    Réponses: 3
    Dernier message: 18/06/2007, 16h45
  5. [LG]Problèmes de types Booléen entier...
    Par youngeikichi dans le forum Langage
    Réponses: 2
    Dernier message: 07/02/2005, 22h27

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