Partage
  • Partager sur Facebook
  • Partager sur Twitter

Affichage d'une grille

    19 septembre 2016 à 13:29:07

    Bonjour à tous,

    je suis en train de réaliser un programme affichant une grille et des informations dedans. Voici déjà une ébauche de l'affichage de la grille :

    #include <stdio.h>
    #include <stdlib.h>
    #include "main.h"
    
    #define X 3	//lignes
    #define Y 4 //colonnes
    #define H 6 //hauteur de ligne
    #define W 18 //longueur de colonne
     
    int main()
    {
    	int a, i, j;
    	Aff_Grille();
    	scanf("%f", &a);
    	return 0;
    }
    
    void Aff_Grille()
    {
    	int grille[X][Y] = {0}, i, j, k, l, m;
    	for (i = 0; i < Y; i++)
    	{
    		for (j = 0; j < X; j++)
    		{
    			printf("+");
    			for (m = 0; m < W; m++)
    				printf("-");
    		}
    		printf("+\n");
    		if (i < (Y-1))
    		{
    			for (l = 0; l < H; l++)
    			{
    				for (k = 0; k < ((W+1)*X); k++)
    				{
    					if (k % (W+1) != 0)
    						printf(" ");
    					else if (k % (W+1) == 0)
    
    						printf("|");
    				}
    				printf("|\n");
    			}
    		}
    	}
    }

    J'aimerais savoir comment afficher du texte dans les cases, sans que cela ne modifie mon tableau; car quand je rentre un texte quelconque dans une case, toute la "structure" du tableau se décale du nombre de caractères insérés. Par exemple, si j'écris "toto", 4 caractères, tout se décale de 4.

    J'ai pensé prendre la chaîne de caractères et ajouter un certain nombre d'espaces automatiquement de façon à ce que toutes les chaînes aient la même taille, mais je ne suis pas sûr que cela résolve mon problème :D.

    Si vous avez une idée, proposez-moi, je suis preneur!

    (J'accepte également les critiques de mon code actuel, qui est, comment dire...immonde je crois) :D

    • Partager sur Facebook
    • Partager sur Twitter
      19 septembre 2016 à 14:32:32

      Pour faire ça tu peux creer des chaine de caractere qui contiennent tout ce que dois avoir ta ligne (à vide) et afficher toutes ces lignes et quand tu dois changer une ligne tu as juste à modifier ta chaine de caractere en mode strcat mais a l'endroit de ta chaine en insertion quoi en mode :

      s1 = bonjour peuple, s2 = le

      s3 = function_insert(s1, s2, 8);

      s3 = bonjour le peuple

      Ou tu utilise la lib lncurses qui te permet de creer un terminal et d'afficher les phrases que tu veux à des index spéciaux et il existe même des fonction pour changer la couleur des char ou même pour creer les tableau, juste à donner width et height et les char qui le construisent et hop ça fait tout tout seul je t'invite à lire de la doc sur cette lib.

      • Partager sur Facebook
      • Partager sur Twitter
      "If someone offers you an amazing opportunity and you're not sure you can do it, say yes -then learn how to do it later."
        19 septembre 2016 à 15:06:36

        Merci pour ta réponse, je vais aller regarder de ce côté ;)
        • Partager sur Facebook
        • Partager sur Twitter
          19 septembre 2016 à 15:46:35

          Si je devais faire un tableau de ce genre, je m'imposerais un nombre limite de caractères des chaînes à afficher. Mettons que je m'impose 6 caractères maxi (bien sûr ce nombre sera #défini, je crois qu'il s'agit de ton X). Dans ce cas, la construction des +----+ du tableau se fera avec ce nombre 6, et le remplissage des cases se fera uniquement avec des chaînes de 6 caractères (pas 5, pas 7 : 6). Je crois que c'est d'ailleurs l'idée que tu avais.

          Pour cela, on peut imaginer une fonction f (lui donner un autre nom, là c'est pour l'explication) qui transforme une chaîne de caractère quelconque en chaîne de 6 caractères. Par exemple elle transformera "anticonstitutionnellement" en "antico", "bof" en "bof   ", "?" en "?     ", etc. On peut même fignoler cette fonction en utilisant un deuxième argument, le type de justification (ajouter les espaces à gauche ? à droite ? des deux côtés ?).

          Alors, pour remplir le tableau avec le contenu de la variable chaine, il suffira de mettre dans le printf non pas chaine mais f(chaine). (Pour une case vide, fabriquer une chaîne de X espaces.)

          (En tant que programmeur du dimanche, je trouve l'exercice très intéressant, et ça me démange d'essayer, d'autant que j'ai toujours du mal avec la gestion des chaînes de caractères... Hop, j'essaie !)

          ----------------------------------------------------

          Re. J'ai terminé le TP ! (Heureusement que PicoDev a trouvé la grossière erreur qui me bloquait, pfouu, que je suis nul en chaînes de caractères !)

          Je pars d'un fichier de ce type, appelé ici "truc.txt" :

          5 3 10
          Nom Prenom Age
          Martin Jean 22
          Dupont Jacques 35
          Dupuis Marc 44
          Nabuchodonosor Balthazar 72
          

          La première ligne donne le nombre de lignes (5), de colonnes (3) et la longueur des cases (ici 10 caractères).

          J'appelle le programme de la façon suivante :

          ./tabul truc.txt
          

          et il affiche :

          +----------+----------+----------+
          |   Nom    |  Prenom  |   Age    |
          +----------+----------+----------+
          |  Martin  |   Jean   |    22    |
          |  Dupont  | Jacques  |    35    |
          |  Dupuis  |   Marc   |    44    |
          |Nabuchodon|Balthazar |    72    |
          +----------+----------+----------+
          

          Comme on le voit, il a centré les données. C'est le comportement par défaut. Mais on peut demander une justification à gauche ou à droite. Par exemple :

          ./tabul truc.txt d
          
          +----------+----------+----------+
          |       Nom|    Prenom|       Age|
          +----------+----------+----------+
          |    Martin|      Jean|        22|
          |    Dupont|   Jacques|        35|
          |    Dupuis|      Marc|        44|
          |Nabuchodon| Balthazar|        72|
          +----------+----------+----------+
          

          (g ou G pour gauche, c ou C pour centre, d ou D pour droite)

          Si dans le fichier de données je change le 10 en 6 les cases seront plus petites :

          +------+------+------+
          |Nom   |Prenom|Age   |
          +------+------+------+
          |Martin|Jean  |22    |
          |Dupont|Jacque|35    |
          |Dupuis|Marc  |44    |
          |Nabuch|Baltha|72    |
          +------+------+------+
          

          (ici j'ai choisi la justification à gauche.)

          labrinds : j'afficherai mon programme quand tu auras fini le tien, on pourra comparer (et les spécialistes du C pourront critiquer mon programme, notamment me hurler dessus parce que j'ai tout mis dans un seul fichier ‒ mais j'ai fait des efforts dans le traitement des erreurs, alors hein...)

          ----------------------------------------------------

          Finalement j'ai modifié le programme pour que l'on puisse spécifier des indicateurs de justification pour chaque colonne. Le fichier d'entrée ressemble donc maintenant à ça :
          5 3 8
          g d c
          Nom Prenom Age
          Martin Jean 22
          Dupont Jacques 35
          Dupuis Marc 44
          Nabuchodonosor Balthazar 72
          
          Ici on demande de justifier les colonnes : à gauche, à droite, au centre. Ça produit :
          +--------+--------+--------+
          |Nom     |  Prenom|  Age   |
          +--------+--------+--------+
          |Martin  |    Jean|   22   |
          |Dupont  | Jacques|   35   |
          |Dupuis  |    Marc|   44   |
          |Nabuchod|Balthaza|   72   |
          +--------+--------+--------+
          

          -
          Edité par robun 20 septembre 2016 à 5:10:57

          • Partager sur Facebook
          • Partager sur Twitter
            21 septembre 2016 à 15:44:51

            Comme deux jours se sont écoulés et que labrinds n'est pas revenu, je poste ma version du sujet sans savoir si ça l'intéressera (labrinds : si j'ai bien compris, ton programme affiche d'abord la grille, et ensuite l'utilisateur rentre du texte qui ira dans la grille, mais peut-être que faire le contraire ‒ ma méthode ‒ te conviendrait ? ou pas ?). J'ai fait ça dans l'esprit d'un petit T.P. pour changer des sempiternels "plus ou moins" ou "pendu". C'est du C99. Je n'ai utilisé que des fonctionnalités basiques (pas de pointeurs ou de récursivité ou autre machin casse-tête pour moi...).

            /* ----------------------------------------------------------
               Affichage de données sous forme d'un joli tableau ASCII
            
               Les données doivent être saisies dans un fichier texte.
               1) La première ligne de ce fichier contient trois nombres :
               - le nombre de lignes (intitulés des colonnes + données) ;
               - le nombre de colonnes ;
               - la taille des cases (en nombre de caractères).
               2) La deuxième ligne contient les indications de justification
               pour chaque colonne.
               3) La ligne suivante contient l'intitulé des colonnes.
               4) Les lignes suivantes contiennent les données.
            
               Les indications de justification sont :
                   g (à gauche), c (centré) ou d (à droite)
               Remarque : on peut rentrer ces caractères en majuscule.
            
               Exemple :
               2 4 6        # 2 lignes de 4 colonnes, cases de 6 caractères
               g c c c      # justification à gauche, centrée, centrée, centrée
               Nom Prenom Age Poste
               Dupont Jacques 25 attaquant
               Martin Jean 30 gardien
               
               Syntaxe : ./tabul fichier
            
               Erreurs :
               - Le fichier ne doit contenir que des caractères ASCII de base.
               - On ne peut pas entrer plus de MAXCOL colonnes.
               - Si le fichier de données contient des mots de plus de 256
               caractères, le programme plante.
               - Le programme lit les données sans se préoccuper de leur
               regroupement par ligne (on peut d'ailleurs tout mettre sur
               une seule ligne), c'est à l'utilisateur de s'assurer qu'elles
               sont correctement ordonnées.
            ---------------------------------------------------------- */
            
            #include <stdlib.h>
            #include <stdio.h>
            #include <ctype.h>
            #include <string.h>
            #include <stdbool.h>
            
            #define MAXCOL 1024 // nombre maximum de colonnes autorisé
            
            /* Caractères indiquant la justification */
            #define JUST_G 'g'  // à gauche
            #define JUST_C 'c'  // centrée
            #define JUST_D 'd'  // à droite
            
            /* Messages d'erreur */
            #define E_FICHIER_NON_SPEC "\rFichier non spécifié."
            #define E_OUVERTURE        "erreur d'ouverture."
            #define E_LIGNE_1          "erreur de lecture ligne 1."
            #define E_LIGNE_2          "erreur de lecture ligne 2."
            #define E_SYNTAXE_2        "erreur de syntaxe ligne 2."
            #define E_DONNEES          "\rDonnées manquantes."
            #define E_FERMETURE        "erreur de fermeture."
            
            /* ------------------------------------------------------- */
            
            bool validjustif(char c)
                /* Vérifie si le caractère c est un indicateur de justification valide. */
                /* (Retourne le résultat du test, donc vrai s'il est valide.)           */
                {
                   return (c == JUST_G || c == JUST_C || c== JUST_D) ;
                }
            
            void errmessage(char* nomfich, char* msg)
                /* Affiche un message d'erreur faisant référence à un nom de fichier
                   puis interrompt le programme. */
                {
                    printf("Fichier %s : %s\n", nomfich, msg) ;
                    exit(EXIT_FAILURE) ;
                }
            
            void printblancs(int n)
                /* Écrit n blancs */
                {
                    for (int i = 1 ; i <= n ; i++ )
                        printf(" ") ;
                }
            
            void affichemot(char* mot, int largeur, char justification)
                /* Écrit un mot limité à 'largeur' caractères et justifié. */
                {
                    int lmot = strlen(mot) ;   // longueur du mot
                    if (lmot >= largeur)
                    {
                        /* Affichage des 'largeur' premiers caractères */
                        for (int l = 0 ; l < largeur ; l++ )
                            printf ("%c", mot[l]) ;
                    }
                    else
                    {
                        /* On ajoute des blancs selon la justification */
                        int blancs = largeur - lmot ;  // nombre de blancs à ajouter
                        switch (justification)
                        {
                            case JUST_G :   /* justification à gauche */
                            {
                                printf("%s", mot) ;     // d'abord le mot
                                printblancs(blancs) ;   // ensuite les blancs à droite
                                break ;
                            }
                            case JUST_C :   /* justification centrée */
                            {
                                int blancsgauche = blancs/2 ;
                                int blancsdroite = blancs - blancsgauche ;
                                printblancs(blancsgauche) ; // d'abord les blancs à gauche
                                printf("%s", mot) ;         // ensuite le mot
                                printblancs(blancsdroite) ; // enfin les blancs à droite
                                break ;
                            }
                            case JUST_D :   /* justification à droite */
                            {
                                printblancs(blancs) ;   // d'abord les blancs à gauche
                                printf("%s", mot) ;     // ensuite le mot
                                break ;
                            }
                        }
                    }
                }
            
            void lignepleine(int ncol, int largeur)
                /* Affichage d'une ligne pleine de 'ncol' colonnes de largeur spécifiée. */
                {
                    for (int i = 1 ; i <= ncol ; i++)
                    {
                        printf("+") ;
                        for (int j = 1 ; j <= largeur ; j++)
                            printf("-") ;
                    }
                    printf("+\n") ;
                }
            
            void lignedata(FILE* fich, int ncol, int largeur, char* tjust)
                /* Affichage d'une ligne de données de 'ncol' colonnes de largeur
                   lues dans le fichier 'fich', avec la justification spécifiée. */
                {
                    char motcourant[256] = "" ;  // mot courant dans le fichier
                    for (int i = 0 ; i < ncol ; i++)
                    {
                        printf("|") ;
                        if (fscanf(fich, "%255s", motcourant) != 1)
                            errmessage("", E_DONNEES) ;
                        affichemot(motcourant, largeur, tjust[i]) ;
                    }
                    printf("|\n") ;
                }
            
            int main(int argc, char* argv[])
            {
                FILE* fich ;            // flux associé au fichier
                int nlig ;              // nombre de lignes à lire
                int ncol ;              // nombre de colonnes à lire
                int largeur ;           // largeur des cases
                char tjust[MAXCOL] ;    // tableau des indicateurs de justification
            
                /* Vérification de la syntaxe de l'appel */
                if (argc <= 1)
                    errmessage("", E_FICHIER_NON_SPEC) ;
            
                /* Ouverture du fichier */
                fich = fopen(argv[1], "r") ;
                if (fich == NULL)
                    errmessage(argv[1], E_OUVERTURE) ;
            
                /* Lecture de la première ligne : nlig, ncol, largeur */
                if (fscanf(fich, "%d %d %d", &nlig, &ncol, &largeur) != 3)
                    errmessage(argv[1], E_LIGNE_1) ;
            
                /* Lecture de la deuxième ligne : indicateurs de justification */
                for (int i = 0 ; i < ncol ; i++)
                {
                    char indic[256] ;
                    if (fscanf(fich, "%255s", indic) != 1)
                        errmessage(argv[1], E_LIGNE_2) ;
                    tjust[i] = tolower(indic[0]) ;
                    if (!validjustif(tjust[i]) || strlen(indic) != 1)
                        errmessage(argv[1], E_SYNTAXE_2) ;
                }
            
                /* Dessin du tableau */
                lignepleine(ncol, largeur) ;
                if (nlig >= 1)
                    lignedata(fich, ncol, largeur, tjust) ; // intitulés du tableau
                lignepleine(ncol, largeur) ;
                for (int i = 2 ; i <= nlig ; i++)
                    lignedata(fich, ncol, largeur, tjust) ; // données du tableau
                if (nlig >= 2)
                    lignepleine(ncol, largeur) ;
            
                /* Fermeture du fichier */
                if (fclose(fich) == EOF)
                    errmessage(argv[1], E_FERMETURE) ;
            
                /* Fin */
                return EXIT_SUCCESS ;
            }
            



            • Partager sur Facebook
            • Partager sur Twitter
              30 juin 2022 à 13:35:55

              Merci pour ton aide, je vais enfin avancer ! A bientôt
              • Partager sur Facebook
              • Partager sur Twitter
                30 juin 2022 à 14:14:55

                Hé, tu es revenu ! :)

                Il y a une erreur dans mon programme : en cas d'erreur de lecture, il ne faut pas faire la suite. Le mieux est d'ajouter un 'else' pour toute la suite.

                • Partager sur Facebook
                • Partager sur Twitter
                  30 juin 2022 à 15:14:52

                  Bonjour,

                  On peut utiliser les spécificateurs de printf() pour justifier à droite ou à gauche sur une largeur déterminée.

                  Centrer nécessite un calcul et de gérer le cas où la division fait perdre une colonne.

                  int main(void) {
                          char * s = "Texte à traiter";
                          int len = 30;
                          // justifié à gauche
                          printf("! %-*s !\n", len, s);
                          // justifié à droite
                          printf("! %*s !\n", len, s);
                          // centré
                          int padl = (len - strlen(s)) / 2;
                          int padr = padl + (len - strlen(s)) % 2;
                          printf("! %*s%s%*s !\n", padl, "", s, padr, "");
                  
                          return 0;
                  }
                  


                  donne :

                  $ gcc -Wall -Wextra 94576234.c
                  $ ./a.out 
                  ! Texte à traiter               !
                  !               Texte à traiter !
                  !        Texte à traiter        !
                  




                  • Partager sur Facebook
                  • Partager sur Twitter

                  Affichage d'une grille

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown