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 :

Scinder un texte en fonction du nombre de caracteres


Sujet :

C

  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur du son
    Inscrit en
    Janvier 2017
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur du son

    Informations forums :
    Inscription : Janvier 2017
    Messages : 12
    Par défaut Scinder un texte en fonction du nombre de caracteres
    Bonsoir,

    J'essaye de créer une fonction permettant de "couper" un texte lorsqu'il est trop long.
    In fine, ce code est censé me servir à couper un texte trop long en sdl et créer une nouvelle ligne.

    Le programme que j'ai créé est fonctionnel, seulement en plus de le trouver peu élégant, j'ai 2 warnings :
    warning: format '%s' expects argument of type 'char *', but argument 2 has type 'char (*)[60]' [-Wformat=]

    Evidemment, je sais que cela va me poser problème pour l'avenir (c'est un problème qui devient récurant pour moi).

    Pourriez vous m'expliquer comment améliorer ce code?
    Notamment en m'expliquant pourquoi un char est différent d'un array? Comment passer de l'un a l'autre? (j'ai beau eu cherché sur internet, je n'ai pas trouvé de réponse compréhensible... )

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    typedef struct
    {
       char texte1[60];
       char texte2[60];
    }Texte;
     
    void ScinderTexte(Texte *x, char testtexte[], int longueur);
     
    int main()
    {
        Texte test;
        memset(&test,0,sizeof(test));
        char testtexte[] = "Alors on va tester cette nouvelle fonction qui me semble etre deja vouer a buger";
     
        ScinderTexte(&test, testtexte, 40);
        printf("%s\n", &test.texte1);
        printf("%s\n", &test.texte2);
     
        return 0;
    }
     
    void ScinderTexte(Texte *x, char testtexte[], int longueur)
    {
        int i =0;
     
        for (i = 0; i < strlen(testtexte); i++)
        {
            if (i < longueur)
            {
                x->texte1[i] = testtexte[i];
            }
            else
            {
                x->texte2[i - longueur] = testtexte[i];
            }
        }
    }

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Concernant le warning, dans printf, "%s" attend un pointeur de caractère, et le nom d'un tableau est convertible en pointeur vers son premier élément, n'ajoute pas un &, ou tu obtiens un pointeur de tableau (ce qui se note char (*)[])

    Concernant la différence entre char et tableau.
    Un tableau de T est une succession d'éléments du type T, en mémoire, un tableau de 8 T est un bloc contigu dont la taille est 8 fois celle d'un T.
    un tableau d'entier (int tab[]) est contient des entiers, un tableau de char des chars, etc.

    D'un point de vue langage, le nom d'un tableau (tab, si je reprends l'exemple précédent) est implicitement convertible en pointeur vers son premier élément (&tab[0])

    char est un des types primitifs, c'est à dire qu'il est fourni par le langage.
    Il a plusieurs propriétés:
    c'est un type entier capable de contenir les nombres de 0 à 127. (c'est à dire la plage 7 bits non signée)
    Il permet de représenter les caractères, c'est à dire les symboles formant les textes (les lettres, les chiffres, la ponctuation, et certains symboles spéciaux)

    Il existe des constantes spéciales, autres que les nombres comme 1, 2 ou 17, qui représentent directement des caractères. elles se notent entre quote simples: 'a' ou '8'Une chaine de caractères est une suite de caractères, c'est à peu près un tableau de caractères, si ce n'est qu'il y a un caractère spécial au bout, pour détecter ce bout: '\0', le caractère nul, qui s'avère valoir 0.


    Par contre, pour l'amélioration générale de ton code, je n'ai plus les réflexes du C, je fais surtout de C++ actuellement.

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    La fonction ScinderTexte() oublie de gérer le terminateur de chaine aussi bien pour texte1 que pour texte2.
    Et attention il y a deux constantes pour des choses similaires (40 et 60!!!), la chaine étant de longueur fixe, la passer en paramètre devient hasardeux
    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
    void ScinderTexte( Texte *x, char const testtexte[] )
    {
        const unsigned longueur = sizeof(x->texte1)/sizeof(*x->texte1) - 1;  // longueur disponible
     
        x->texte1[longueur]  = '\0';  // terminateur 1er texte est au plus ici, si le second texte est rempli
        x->texte2[0] = '\0';              // si chaine 'courte' le texte2 sera vide
     
        for ( int i = 0 ; i <= strlen(testtexte) ; i++ ) { // aller jusqu'au terminateur inclus
            if ( i < longueur ) {
                x->texte1[i] = testtexte[i];
            }
            else {
                x->texte2[i - longueur] = testtexte[i];
            }
        }
    }

  4. #4
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Bonjour,

    Citation Envoyé par ternel Voir le message
    ......
    c'est un type entier capable de contenir les nombres de 0 à 127. (c'est à dire la plage 7 bits non signée)
    Il permet de représenter les caractères, c'est à dire les symboles formant les textes (les lettres, les chiffres, la ponctuation, et certains symboles spéciaux).......
    Quelque précision. Le type char (type caractères) est un type codé sur 8 bits c'est-à-dire (1 octet soit exactement 2^8 =) 256 combinaisons possibles. Interprétés comme des caractères, mais qui peuvent également être utilisé comme des entiers. Le type char (caractère) peut donc contenir un caractère du jeu de caractères de la machine que vous avez (Jeu de caractères de la machine tout simplement parce que votre ordinateur possède une table de caractère; par défaut, ces caractères sont au nombre de 256 et donc indexé par la valeur octet du caractère à afficher parmi les 256 combinaisons. En parle de représentation ASCII étendue de la machine. À l’origine le code ASCII est codé sur 7 bits c'est-à-dire 128 combinaisons possibles de 0 à 127 caractères pour être exacte. Cependant pour la diversité des langues du monde elle a été étendu ainsi donc en France ou pour d’autres pays le code ASCII a été étendu pour contenir et supporter les accents et certains symboles et donc elle utilise les 256 combinaisons. A titre d'exemple, le BIOS possède sa propre table ASCII étendue pour les caractères graphiques comme les bordures, etc.). Ainsi donc les caractères sont coder sur 8 bits chose qui n’est effectivement pas obligatoire de plus les caractères ne sont pas signés ou non signés par défaut cela dépend de la machine que vous possédez soit les caractères sont non signé soit elles ne le sont pas. Tout de même on remarque que les valeurs imprimables sont toujours positives donc, on peut très bien affirmer que la table ASCII est codée sur 8 bits non signés 0-255. (les unsigned suit la loi des %2^n dont "n" correspond au nombre de bits du type concerné. Les caractères imprimables sur 8 bits vont donc de 0 à 255) tant dit que les signés sont de -128 à 127 pour des machines à complément à deux. Comme tout dépend de la machine, il est alors important voire prudent de spécifier si l’on utilise des caractères comme étend des entiers ou pas (signed / unsigned).

    Pour conclure, le type caractère est bien sûr 8bits soit un octet (qui est l’unité de donnée la plus petite) qui peut contenir un caractère du jeu de caractères (ASCII) de la machine que vous possédez.

    à bientôt

  5. #5
    Membre averti
    Homme Profil pro
    Ingénieur du son
    Inscrit en
    Janvier 2017
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur du son

    Informations forums :
    Inscription : Janvier 2017
    Messages : 12
    Par défaut
    Bonjour, et merci pour vos réponses !

    #ternel, #sambia39 : Merci pour toutes ces précisions. Je pense être loin d'être le seul débutant à avoir voulu avancé trop vite en utilisant des concepts sans réellement les saisir totalement... Je pense qu'il est temps pour moi d'étudier d'avantage les concepts de base avant de faire n'importe quoi par la suite ^^.

    #dalfab : Effectivement je n'avais pas pensé au '\0' (faire un code à 90% c'est ma spécialité :p)
    En ce qui concerne le int longueur, je sais que c'est un choix bancale, mais il me permet de scinder le texte où je veux :
    je m'explique, avec une valeur qui n'est pas en paramètre, ma fonction coupe automatiquement le texte même en plein mot !
    En changeant manuellement le paramètre, je peux rapidement scinder ma phrase mot a mot.
    Je pourrais effectivement faire cela en changeant les char de ma structure, mais comme j'utilise une gestion etat machine pour mes dialogues, je n'utilise que ces deux char à chaque cas (ils doivent donc être fixes).

    Ma technique ressemble donc vraiment à du bricolage mais je ne vois pas vraiment comment faire autrement.
    ps : peut être une boucle sur j qui compare testchar et " " et qui l'ajoute ou le retire à longueur? Je sais pas trop là...

    code en SDL :
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <SDL/SDL.h>
    #include <SDL/SDL_ttf.h>
     
    typedef struct
    {
       char texte1[60];
       char texte2[40];
    }Texte;
     
    void ScinderTexte(Texte *x, char testtexte[], int longueur);
    SDL_Surface *Initialisation();
    SDL_Surface *LoadImage32(const char *fichier_image);
    void Apply_Surface(int x, int y, SDL_Surface *source, SDL_Surface *destination, SDL_Rect *clip);
     
    int main(int argc, char *argv[])
    {
        SDL_Surface *screen = Initialisation();
        TTF_Init();
        TTF_Font *fontM = NULL;
        fontM = TTF_OpenFont("MOD.ttf", 30);
        SDL_Color noir = {0, 0, 0};
     
        Texte test;
        memset(&test,0,sizeof(test));
        char testtexte[] = "Alors on va tester cette nouvelle fonction qui me semble etre deja vouer a bugger";
     
        SDL_Surface *fond = LoadImage32("fond_jeu.bmp");
        SDL_Surface *txt[3];
        txt[0] = TTF_RenderText_Blended(fontM, testtexte, noir);
     
     
        Apply_Surface(0, 0, fond, screen, NULL);
     
     
        if (strlen(testtexte) < 40)
        {
             Apply_Surface(0, 100, txt[0], screen, NULL);
        }
        else
        {
            ScinderTexte(&test, testtexte, 46);
            txt[1] = TTF_RenderText_Blended(fontM, test.texte1, noir);
            txt[2] = TTF_RenderText_Blended(fontM, test.texte2, noir);
            Apply_Surface(0, 100, txt[1], screen, NULL);
            Apply_Surface(0, 150, txt[2], screen, NULL);
        }
     
        SDL_Flip(screen);
        SDL_Delay(4000);
        SDL_FreeSurface(fond);
        SDL_Quit();
     
        return 0;
    }
     
    void ScinderTexte(Texte *x, char testtexte[], int longueur)
    {
     
        x->texte1[longueur] = '\0';
        x->texte2[0] = '\0';
        int i =0;
     
        for (i = 0; i <= strlen(testtexte); i++)
        {
            if (i < longueur)
            {
                x->texte1[i] = testtexte[i];
            }
            else
            {
                x->texte2[i - longueur] = testtexte[i];
            }
        }
    }
     
    SDL_Surface *Initialisation()
    {
        SDL_Surface *screen;
        screen = SDL_SetVideoMode(1024, 640, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
     
        if (SDL_Init(SDL_INIT_VIDEO) == -1)
        {
            printf("Can't init SDL: %s\n", SDL_GetError());
        }
     
        SDL_WM_SetCaption("Projet Eden", NULL);
     
          return screen;
    }
     
    SDL_Surface *LoadImage32(const char *fichier_image)
    {
        SDL_Surface *image_optimized;
        SDL_Surface *image_tmp = SDL_LoadBMP(fichier_image);
        if (image_tmp == NULL)
        {
            printf("Image %s introuvable !\n", fichier_image);
            system ("pause");
            exit(-1);
        }
     
        image_optimized = SDL_DisplayFormat(image_tmp);
        SDL_FreeSurface(image_tmp);
        return image_optimized;
    }
     
    void Apply_Surface(int x, int y, SDL_Surface *source, SDL_Surface *destination, SDL_Rect *clip)
    {
        SDL_Rect offset;
        offset.x = x;
        offset.y = y;
     
        SDL_BlitSurface(source, clip, destination, &offset);
    }

  6. #6
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Pour le coup, je corrige certaines choses dites par Sambia.

    Il est prévu par la norme que:
    • char puisse représenter chaque valeurs de 0 à 127 (inclu)
    • char soit équivalent à l'un des types unsigned char ou signed char (il doit être convertible, sans perte, vers et depuis cet équivalent).
    • char reste un type distinct de ces deux types. (l'équivalent est défini par le compilateur, et il est envisageable qu'il soit réglable)
    • sizeof retourne toujours un entier, et sizeof(char) == 1.


    Mais, un char n'est pas contraint à faire 8 bits.
    Il peut faire n'importe quelle taille, et la constante CHAR_BIT (de <limits.h>) défini le nombre de bits dans un char.
    Il existe de vraie machine qui ont des chars de 16 ou 32, voire 64 bits.

    la seule relation vraie est: 1 = sizeof(char) ≤ sizeof(short) ≤ sizeof(int) ≤ sizeof(long) ≤ sizeof(long long).

    Cela dit, concrètement, les machines normales ont toutes des char de 8 bits.

    Le problème des débutants n'est pas char en lui-même, mais le concept de chaine de caractères, qui n'est quasiment jamais correctement présenté dans les cours.
    C'est dommage, car après avoir expliqué brièvement les détails, on ne peut plus se tromper que par inadvertance.

  7. #7
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Par contre, la SDL fournit une fonction pour faire ce travail.

    la fonction TTF_RenderText_Blended_Wrapped, présente dans le module ttf de la SDL2.

    Je t'invite très fortement à utiliser la SDL2, la version beaucoup plus moderne de la SDL.

  8. #8
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    ternel met le doigt là où ça coince, selon moi. Quand l'OP écrit cela :

    Citation Envoyé par edenstark Voir le message
    Notamment en m'expliquant pourquoi un char est différent d'un array? Comment passer de l'un a l'autre? (j'ai beau eu cherché sur internet, je n'ai pas trouvé de réponse compréhensible... )
    ..cela montre qu'il faut repasser sans tarder sur les fondamentaux : qu'est qu'une chaîne de caractères, en langage C ? On peut trouver les détails par exemple ici ou (pour les constantes).

    TL;DR: une chaîne de caractères C :

    • n'est définie par aucun type (ni natif, ni construit) du langage ;
    • est un pointeur vers une séquence d'éléments de type char dont le dernier - et seulement le dernier, puisqu'il termine la chaîne - vaut impérativement '\0'.

    On peut aussi préciser :

    • qu'un pointeur de type char * peut être une chaîne de caractères mais que tous les pointeurs de type char * ne sont pas des chaînes de caractères ;
    • qu'un élément de type char au sein d'une chaîne peut coder un caractère mais que tous les éléments de type char au sein d'une chaîne ne codent pas un caractère : ça dépend de l'encodage.


    Je me permets de proposer une implémentation commentée de la solution à ton problème à titre d'exemple, basé sur la fonction strlcpy, ré-implémentée car ne faisant pas partie de la bibliothèque standard. Ce programme est assez primitif : il n'est pas word-aware et « coupera » la chaîne après exactement le nombre d'octets spécifié. S'il te prend l'envie d'ajouter cette fonctionnalité, tu auras besoin de strchr et / ou strtok. Pour la même raison, mon programme ne fonctionnera pas en UTF-8 notamment où certains caractères (la plupart en fait) sont codés sur plusieurs octets.

    Code justify.c : 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
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
     
    #define CHUNK_SIZE_MIN     ((size_t)  1) // minimum line length
    #define CHUNK_SIZE_MAX     ((size_t)160) // maximum line length
    #define CHUNK_SIZE_DEFAULT ((size_t) 80) // default line length
    // compile-time checks
    _Static_assert(CHUNK_SIZE_DEFAULT >= CHUNK_SIZE_MIN, "default line length is too small");
    _Static_assert(CHUNK_SIZE_DEFAULT <= CHUNK_SIZE_MAX, "default line length is too great");
     
     
    /*
     Copies at most 'count' - 1 bytes from 'src' to buffer 'dst'.
     Similar to non-standard function strlcpy.
     
     'dst' must point to a valid buffer of at least 'count' bytes size.
     'src' must be NUL-terminated.
    */
    size_t my_strlcpy(char *dst, const char *src, size_t count) {
        if (count == 0) return 0;
     
        const char *src_ptr = src;
     
        while ((size_t)(src_ptr - src) < count - 1 && *src_ptr)
            *dst++ = *src_ptr++;
     
        *dst = '\0';
     
        return src_ptr - src;
    }
     
     
    int main(int argc, char *argv[]) {
        if (argc > 2) { // program takes at most one argument
            fprintf(stderr, "error: too many arguments\n"
                            "usage: justify [line length]\n");
            return 1;
        }
     
        size_t chunk_size = CHUNK_SIZE_DEFAULT; // number of characters per line
        if (argc == 2) { // parse line length argument, if any
            char *end;
            long i = strtol(argv[1], &end, 10);
     
            // error handling code follows
            if (errno == ERANGE                                         // native range error
             || *end                                                    // format error
             || i < (long)CHUNK_SIZE_MIN || (size_t)i > CHUNK_SIZE_MAX) // conversion error (i == 0), or program-specific range error
            {
                fprintf(stderr, "error: line length provided is invalid: '%s'\n", argv[1]);
                if (errno == ERANGE) errno = 0; // we handled the error: reset errno
                return 2;
            }
     
            chunk_size = (size_t)i; // argument is ok, use it
        }
     
        const char *const test = // 'Lorem ipsum' from Wikipedia:
           "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
           "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut "
           "enim ad minim veniam, quis nostrud exercitation ullamco laboris "
           "nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor "
           "in reprehenderit in voluptate velit esse cillum dolore eu fugiat"
           " nulla pariatur. Excepteur sint occaecat cupidatat non proident,"
           " sunt in culpa qui officia deserunt mollit anim id est laborum.",
                   *str = test;
     
        char buf[chunk_size + 1]; // the buffer to use for output
     
        /* for each chunk of size 'chunk_size' in the input string,
           write it on a single line */
        size_t count; // number of bytes copied to the output buffer minus the NUL character, at each iteration
        while ( (count = my_strlcpy(buf, str, chunk_size + 1)) ) {
            puts(buf); // write the line to standard output
            str += count; // advance input string pointer by the number of bytes read
        }
     
        return 0;
    }

    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
    $ gcc -std=c11 -pedantic -Wall -Wextra -o justify justify.c
    $ ./justify 37
    Lorem ipsum dolor sit amet, consectet
    ur adipiscing elit, sed do eiusmod te
    mpor incididunt ut labore et dolore m
    agna aliqua. Ut enim ad minim veniam,
     quis nostrud exercitation ullamco la
    boris nisi ut aliquip ex ea commodo c
    onsequat. Duis aute irure dolor in re
    prehenderit in voluptate velit esse c
    illum dolore eu fugiat nulla pariatur
    . Excepteur sint occaecat cupidatat n
    on proident, sunt in culpa qui offici
    a deserunt mollit anim id est laborum
    .

    Mais la manipulation de texte, que j'entends dans le cas général, si on la veut robuste et portable et sans se limiter à l'anglais, c'est une putain de prise de tête. Je t'invite donc à te faciliter la vie en suivant les conseils avisés de ternel :

    Citation Envoyé par ternel Voir le message
    Par contre, la SDL fournit une fonction pour faire ce travail.

    la fonction TTF_RenderText_Blended_Wrapped, présente dans le module ttf de la SDL2.

    Je t'invite très fortement à utiliser la SDL2, la version beaucoup plus moderne de la SDL.

  9. #9
    Membre très actif
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 548
    Par défaut
    Bonsoir,

    Citation Envoyé par ternel Voir le message
    Pour le coup, je corrige certaines choses dites par Sambia.

    Il est prévu par la norme que:
    • char puisse représenter chaque valeurs de 0 à 127 (inclu)
    • char soit équivalent à l'un des types unsigned char ou signed char (il doit être convertible, sans perte, vers et depuis cet équivalent).
    • char reste un type distinct de ces deux types. (l'équivalent est défini par le compilateur, et il est envisageable qu'il soit réglable)
    • sizeof retourne toujours un entier, et sizeof(char) == 1.


    Mais, un char n'est pas contraint à faire 8 bits.
    Il peut faire n'importe quelle taille, et la constante CHAR_BIT (de <limits.h>) défini le nombre de bits dans un char.
    Il existe de vraie machine qui ont des chars de 16 ou 32, voire 64 bits.

    la seule relation vraie est: 1 = sizeof(char) ≤ sizeof(short) ≤ sizeof(int) ≤ sizeof(long) ≤ sizeof(long long).

    Cela dit, concrètement, les machines normales ont toutes des char de 8 bits.

    Le problème des débutants n'est pas char en lui-même, mais le concept de chaine de caractères, qui n'est quasiment jamais correctement présenté dans les cours.
    C'est dommage, car après avoir expliqué brièvement les détails, on ne peut plus se tromper que par inadvertance.
    Je suis d’avis que l’on me corrige si je me trompe et mieux encore qu’on m’explique pourquoi je me suis trompé; surtout que cela me permet de comprendre et d’apprendre davantage. Cependant, je me permets également de corriger certaines choses que vous avez dit ou du moins éclaircir certains points.

    La taille d’un char est définie par le type de compilateur, mais dépend surtout de la machine sur laquelle on travaille. La norme garantit un minima de 8 bits qui est de l’unité de données les plus petites utilisées pour les caractères. Elle le fixe explicitement et le rend obligatoire dans les fichiers d’en-tête <limits.h> qui fixent égalements ces caractéristiques pour chaque implémentation particulière.
    "sizeof"dans les premières versions renvoie un entier. Cependant, la norme le rend explicitement dépendant de l’implémentation, mais demande que "size_t" soit définie. L’opérateur "sizeof" renvoie donc le nombre d’octets requis pour stocker un objet du type types, le résultat renvoyé est une constante du type "size_t" et cet opérateur, peut être utilisé sur un type. Comme vous laviez dit, "sizeof" d’un caractère renverra toujours 1 c’est vrai, mais ce 1 signifie 1 octet parce que "sizeof" vous donne le nombre d’octets permettant de stocker un caractère et cette taille est le minimum recommander. Pour être encore plus précis, la représentation d’un type dépend du mode de représentation des données du compilateur qui est conditionné par l’architecture machine. Ainsi donc, il est tout à fait normal que sur une machine 32 bits on obtienne un "char" codé sur 8 bits aussi bien sur une architecture 32 que 64 (LP32, ILP32, LP64, LLP64, ILP64)
    la taille des chars dépend également de l’encodage utilisée:
    • Un caractère ASCII en codage 8 bits (1 octet).
    • Un caractère ISO-8895-1 dans l'encodage ISO-8859-1 est de 8 bits (1 octet).
    • Un caractère Unicode en codage UTF-8 est compris entre 8 bits (1 octet) et 32 bits (4 octets).
    • Un caractère Unicode dans le codage UTF-16 est compris entre 16 (2 octets) et 32 bits (4 octets)
    • Un caractère Unicode dans l'encodage UTF-32 est toujours 32 bits (4 octets).


    Toutefois, je suis d’accord avec vous sur le fait que le problème des débutants ou étudiants n’est pas le type "char" en lui-même, mais plutôt les chaînes de caractères mais au fond, il s’agit plus exactement de la manipulation et la compréhension des pointeurs (en clair manipulation d’adresse mémoire à travers les pointeurs). Mon intervention précédente apportait juste quelques éclaircissements sur les caractères et leur encodage même-ci, l'on juge que cela n'a pas d'intérêt et personnellement, je vois un intérêt à la compréhension de certaines choses exemple, vous avez écrit :
    Citation Envoyé par ternel Voir le message
    Il existe des constantes spéciales, autres que les nombres comme 1, 2 ou 17, qui représentent directement des caractères. elles se notent entre quote simples: 'a' ou '8'Une chaine de caractères est une suite de caractères, c'est à peu près un tableau de caractères, si ce n'est qu'il y a un caractère spécial au bout, pour détecter ce bout: '\0', le caractère nul, qui s'avère valoir 0.
    . Or, les constantes qui représentent directement les caractères en question sont en réalité des nombres entiers écrits sous forme d’un caractère (interprété comme des caractères mais) qui correspondent en réalité à la valeur du caractère dans le jeu de caractères (ASCII), exemple ‘8’ est en réalité 56 qui n’a rien à voir avec la valeur 8 = "Backspace" ou encore quant vous dite :
    Citation Envoyé par ternel Voir le message
    Une chaine de caractères est une suite de caractères, c'est à peu près un tableau de caractères
    Une chaîne de caractères est une suite de caractères contigus et ce n’est pas à peu près un tableau, c’est bien un tableau de type caractère dont le dernier correspond au caractère NULL ‘\0’ (En langage C, il n'existe pas de type chaîne de caractère) Bref, mon idée de départ était juste d'apporté quelque éléments.

    à bientôt

  10. #10
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Quand je parlais d'entier pour sizeof, je ne parlais pas de int, mais du fait que la valeur est un multiple entier (au sens strictement mathématique) de la taille d'un char.
    Mais ce char n'est pas nécessairement la taille d'un octet.
    L'immense majorité d'entre nous travaillons sur des architectures où c'est le cas, et nous ne verrons probablement jamais autre chose. Il n'empêche que ça existe, que la norme l'autorise, et que ça peut jouer des tours.
    Les 5 modèles que tu cites sont tous dans ce cas, et couvrent les architectures x86 et x86_64 pour les systèmes *nixoïdes ou windowsiens. C'est à dire tous les ordinateurs d'utilisateurs "normaux".
    Pour les micro systèmes et les super calculateurs, la situation n'est pas toujours aussi vraie.

    Pour le reste, nous sommes visiblement d'accord.
    J'ai toujours un doute sur la nature exacte d'une chaîne de caractères, tout particulièrement, sur le type précis d'une littérale de chaîne de caractère, comme [c]"bidule"[c/].
    Ne sachant jamais précisément, je considère que c'est toujours le type le moins pratique entre char const* et char const[].

  11. #11
    Membre averti
    Homme Profil pro
    Ingénieur du son
    Inscrit en
    Janvier 2017
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur du son

    Informations forums :
    Inscription : Janvier 2017
    Messages : 12
    Par défaut
    Bonjour !

    Et bien à ce que je vois, mon message aura au moins permis de lancer un petit débat ^^.
    Pour en revenir a mon problème, entre vos explications et la lecture fourni par Matt, je pense maintenant avoir saisi que je n'avais jusqu'alors rien saisi ! Merci de m'avoir éclairé !
    #Matt Houston : Concernant ton code, pour mon niveau il me paraît trop complexe. N'étant pas à l'aise avec la manipulation des bytes, je ne pense pas l'utiliser pour l'instant. D'autant plus que je n'aime pas utiliser un code que je ne comprend pas totalement ou que je n'ai pas créé. Cependant merci pour cet exemple, il est certain que je m'en servirai dans quelques mois ^^.

  12. #12
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Et c'est sage, mais note que l'algorithme de justification en lui-même ne se situe qu'entre les lignes 72 et 80, commentaires compris. En plus de cela, il n'est nécessaire de comprendre que ce que fait strlcpy et non comment elle le fait : c'est l'intérêt de la modularité.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2010] Comment rajouter du texte dans une cellule en fonction du nombre de pages
    Par Bzh_novice dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 17/10/2015, 09h27
  2. Réponses: 4
    Dernier message: 28/03/2006, 19h51
  3. Réponses: 4
    Dernier message: 31/10/2005, 17h48
  4. affichage dans une boite de texte en fonction d'un choix
    Par bachilbouzouk dans le forum ASP
    Réponses: 3
    Dernier message: 19/04/2005, 14h53
  5. [CR] mise en forme d'un champs texte en fonction des données
    Par niPrM dans le forum SAP Crystal Reports
    Réponses: 6
    Dernier message: 29/06/2004, 11h57

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