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 :

Mini-string en C (Windows)


Sujet :

C

  1. #21
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Par défaut
    OK,

    Apparemment LPTSTR est accepté sans problème si LPCTSTR est attendu.
    Exact ?

    Est-ce le cas aussi avec LPCWSTR (quelle est la nuance) ?

    P.S. :
    j'ai une "undefined reference" pour _sctprintf ??
    avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <stdlib.h>
    #include <stdio.h>
    #include <SDL\SDL.h>
    #include <windows.h>
    #include <time.h>
    #include <tchar.h>
    #include <dirent.h>
    #include <commctrl.h>
    #include <string.h>
    #include <FMOD/fmod.h>
    #include <SDL/SDL_ttf.h>
    #include <unistd.h>
    #include <SDL/SDL_getenv.h>

  2. #22
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 403
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 403
    Par défaut
    Ben oui c'est le principe, on peut copier un pointeur non-const vers un pointeur const, mais pas l'inverse:
    • void* -> const void*
    • LPSTR -> LPCSTR
    • LPWSTR -> LPCWSTR
    • LPTSTR -> LPCTSTR

    Normalement, le linker ne devrait jamais voir "_sctprintf": Selon les options de compilation du projet, il devrait voir "_scprintf" ou "_scwprintf" (parce que _sctprintf est une macro.

    Si ce n'est pas le cas, ça doit vouloir dire que tu utilises MinGW et son <tchar.h> est incomplet. Auquel cas, tu peux rajouter ceci dans ton fichier source:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #ifndef _sctprintf
    #ifdef _UNICODE
    #define _sctprintf _scwprintf
    #else
    #define _sctprintf _scprintf
    #endif
    #endif
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #23
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Par défaut
    Bonsoir,

    Encore des questions sur ce sujet avec des structures :

    En dehors de la ligne 28 , l'exemple de code ci-dessous est-il 100% correct ?

    Sur la ligne 28, j'ai un doute , pouvez m'expliquer si cela est incorrect dans le main.

    Je suppose alors qu'il faille faire une fonction telle la ligne 31.

    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
    typedef struct
    {
        char *chaine;
     
        // ...
     
    } Texte;
     
    Texte *createTexte(char *chaine)
    {
        Texte *TxtTmp;
        TxtTmp = malloc(sizeof(Texte));
     
        TxtTmp->chaine = malloc(160*sizeof(char));
        strcpy(TxtTmp->chaine,chaine);
     
        // ...
     
        return TxtTmp;
    }
     
    //  Dans le main :
    // ...
     
    Texte *Txt1 = createTexte(" Texte1 ");
    Texte *Txt2 = createTexte(" Texte2 ");
     
    Txt1->chaine =" Texte1 modifié   ";
     
    // prototype fonction : void modifTexte(Texte *TxtVar, char *chaine); 
    modifTexte(Txt1, " Texte1 modifié   ");
    PS : en relisant avant de poster, je me demande aussi si il ne faut pas allouer les éléments (TxtTmp->chaine) avant la structure (TxtTmp) elle-même ?
    L'ordre a t_il une importance ?

    Et pour free (doit-on libérer obligatoirement tous les éléments avant la structure) ?

  4. #24
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Sur la ligne 28, j'ai un doute , pouvez m'expliquer si cela est incorrect dans le main.
    Bin tu fait pointer ton pointeur vers une chaîne constante, ça risque à un moment de peut-être te poser des soucis. L'idéal c'est de faire une fonction comme par exemple strdup qui fait une copie de la chaîne constante passée en paramètre tout en allouant un espace assez grand pour la contenir sur le pointeur qui tu auras définit en avance.

    J'ai un module très complet (qu'il faudrait que je mette à jour pour quelques optimisations) qui est fonctionnel: http://sourceforge.net/projects/cstr/, tu peux t'en inspirer si tu le souhaite ou même encore mieux, tu peux l'utiliser

    en relisant avant de poster, je me demande aussi si il ne faut pas allouer les éléments (TxtTmp->chaine) avant la structure (TxtTmp) elle-même ?
    L'ordre a t_il une importance ?
    L'idéal c'est d'allouer ta structure puis ensuite ses membres lorsque cela est nécessaire. Par exemple pour ta chaîne, n'alloue l'espace que lorsque tu utilises une fonction qui va la remplir sauf si tu utilises un constructeur qui prend en paramètre une chaîne.

    Et pour free (doit-on libérer obligatoirement tous les éléments avant la structure) ?
    Oui il faut en fait libérer les différents espaces mémoire dans le sens inverse de l'allocation donc par exemple :

    Allocations :
    • Txt1
    • Txt1->chaine


    Libérations :
    • Txt1->chaine
    • Txt1


    Si tu libérerais ta structure avant ta chaîne, tu perdrais le pointeur pointant ta chaîne et donc tu as une fuite mémoire.
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  5. #25
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 403
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 403
    Par défaut
    Pourquoi allouer 160*sizeof(char) quand tu peux allouer (strlen(chaine)+1) * sizeof *chaine ?

    Aussi, tu devrais déclarer createTexte() en Texte *createTexte(const char *chaine) vu que la fonction ne modifie pas la chaîne passée en paramètre.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #26
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Par défaut
    Bonjour,

    Merci pour vos réponses :
    L'idéal c'est de faire une fonction comme par exemple strdup qui fait une copie de la chaîne constante passée en paramètre tout en allouant un espace assez grand pour la contenir sur le pointeur qui tu auras définit en avance.
    OK, je n'avais encore jamais vu strdup , mais avec strcpy cela revient au même ? (vers un pointeur alloué et avec const char *chaine)
    En l’occurrence le pointeur est celui de ma structure et je veux en modifier la chaine.

    Pourquoi allouer 160*sizeof(char) quand tu peux allouer (strlen(chaine)+1) * sizeof *chaine ?
    Justement, lors de la création, j’alloue une taille maxi ainsi je peux (avec ma fonction modifTexte) remplacer la chaine initiale par une chaine plus longue.
    L'idéal serait évidement de "désallouer" puis de ré-allouer à la bonne taille.

    Mais, vous l'aurez compris, je suis encore en expérimentation. Notamment avec les structures :
    L'idéal c'est d'allouer ta structure puis ensuite ses membres lorsque cela est nécessaire.
    Je trouve bizarre que l'on puisse réserver de la mémoire pour une structure alors qu'on ne connait pas la taille de ses membres.
    Mais bon le C est tout sauf intuitif

    Merci Franck pour le module, mais le source n'est pas donné ?

  7. #27
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Citation Envoyé par nanosoft Voir le message
    OK, je n'avais encore jamais vu strdup , mais avec strcpy cela revient au même ? (vers un pointeur alloué et avec const char *chaine)
    En l’occurrence le pointeur est celui de ma structure et je veux en modifier la chaine.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    char * strdup (const char * s_str)
    {
       char * s = NULL;
     
       if (s_str)
       {
          s = malloc (strlen (s_str) + 1);
     
          if (s)
             strcpy (s, s_str);
       }
     
       return s;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ta_structure->ta_chaine = strdup ("une chaine");
    Citation Envoyé par nanosoft Voir le message
    Je trouve bizarre que l'on puisse réserver de la mémoire pour une structure alors qu'on ne connait pas la taille de ses membres.
    Mais bon le C est tout sauf intuitif
    Disons que la taille de la chaîne on s’en fout car ce n'est qu'un pointeur qui pointera vers une autre zone de la mémoire lorsque l'allocation sera fait par la suite. Sinon la taille de la structure sera égale à la somme de la taille de ses membres, ça c'est suivant l'implémentation de l'OS sur lequel tu travailles mais dans la plupart des cas un pointeur vaut 4 octets si je ne me trompe pas, l'opérateur sizeof (ton_pointeur); devrait te donner le résultat correct.

    Citation Envoyé par nanosoft Voir le message
    Merci Franck pour le module, mais le source n'est pas donné ?
    Bin si il est livré, c'est une archive contenant tous les fichiers ici présent: http://sourceforge.net/p/cstr/code/4/tree/ mais bien entendu, il faut que je retravaille tout ca, ce code date un peu, j'était un peu moins expérimenté par rapport à maintenant
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  8. #28
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Par défaut
    OK,

    J'ai fait ma fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void modifTexte(Texte *txt1, const char *chaine)
    {
        free(txt1->chaine);
        txt1->chaine = malloc((strlen(chaine)+1) * sizeof *chaine);
        strcpy(txt1->chaine,chaine);
    }
    Cela à l'air de bien marcher est-ce qu'elle est propre ?

    Y a t-il un moyen de connaître la taille allouée d'une chaîne ?
    Car effectivement avec sizeof on a la taille du pointeur (4).
    Et strlen ne donne que le nombre de caractère avant le '\0'

  9. #29
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Comme ça c'est mieux:
    • Tester les arguments passés à la fonction
    • Tester la chaîne avant de la supprimer
    • Tester la chaîne avant d'essayer de la remplir

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void modifTexte(Texte *txt1, const char *chaine)
    {
        if (txt1 != NULL && chaine != NULL)
        {
            if (txt1->chaine != NULL)
                free(txt1->chaine);
     
            txt1->chaine = malloc(strlen(chaine)+1);
     
            if (txt1->chaine != NULL)
                strcpy(txt1->chaine,chaine);
        }
    }
    Le * sizeof *chaine n'est pas nécessaire dans l'allocation car un char vaut 1 donc inutile d'alourdir le code si ce n'est pas nécessaire

    Citation Envoyé par nanosoft Voir le message
    Y a t-il un moyen de connaître la taille allouée d'une chaîne ?
    Car effectivement avec sizeof on a la taille du pointeur (4).
    Et strlen ne donne que le nombre de caractère avant le '\0'
    Tu ne peux pas connaître la taille allouée à un moment donné, il faut que tu en garde une trace dans ton programme car il n'existe pas de moyen pour savoir quelle est la taille d'un espace pointé par pointeur. Sinon pour connaître la taille de l'espace pour ta chaîne au moment où tu fais l"allocation bin ce sera simplement strlen(chaine)+1 (rappel toi qu'un char vaut 1 octet donc le calcul est simple à faire )
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  10. #30
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juin 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2012
    Messages : 257
    Par défaut
    Merci

Discussions similaires

  1. problème fin de string sous windows 98
    Par LAPLACE dans le forum Windows
    Réponses: 1
    Dernier message: 07/03/2006, 12h09
  2. Réponses: 4
    Dernier message: 30/01/2006, 20h50

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