Probleme de language c

Résolu
PADYVEN Messages postés 69 Date d'inscription lundi 10 février 2003 Statut Membre Dernière intervention 29 août 2012 - 28 déc. 2007 à 14:01
PADYVEN Messages postés 69 Date d'inscription lundi 10 février 2003 Statut Membre Dernière intervention 29 août 2012 - 29 déc. 2007 à 06:29
Bonjour quelqu'un pourrais jetter un oeil et me dire la les boulettes
du code suivant
PS je debute en c ne soyer pas tueur

char *CentreTexte(char *Texte,int nbCaractereMax)
{
char *tampon=NULL;
int calcul=(nbCaractereMax-strlen(Texte))/2;
tampon=malloc(sizeof(char)*nbCaractereMax+1);
ZeroMemory (tampon,nbCaractereMax) ;
if (calcul>=0)
{
while(calcul!=0)
{
strcat(tampon," ");
calcul--;
}
strcat(tampon,Texte);
}
else
{
strcpy(tampon,Texte);
}
return tampon;
free (tampon);
}

merci beaucoup

13 réponses

SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
28 déc. 2007 à 16:07
Ce n'est pas le système qui détermine la taille d'un char mais le compilateur. Une fois compilé, ton char fera un octet définitivement. (et de toute façon, les caractères ascii font tous 1 octets alors...).

Le ZeroMemory est, ici, complètement inutile. En toute logique, il est complètement inutile de remplir un tableau de 0 quand on insère un texte immédiatement après.

while(calcul!=0)

    {

        strcat(tampon," ");

        calcul--;

    }

strcat coute déjà assez cher comme ça, du fait qu'il parcours toute la chaine avant de copier le texte. Si c'est pour copier un seul caractère...
Un pointeur positionné une fois en fin de chaine fait l'affaire.

C++ (@++)<!--
3
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
28 déc. 2007 à 16:32
Tien, j'ai refais rapidement ton code:

char *CentreTexte(char *Texte, char *tampon, int nbCaractereMax)
{
    char *c = tampon;
    int len = strlen(Texte);

    if (nbCaractereMax > len) {
        int calcul = ((nbCaractereMax-len)/2)+(int)c;
        while(c < (char*)calcul) *c++ = ' ';
    }

    strcpy(c,Texte);

    return tampon;
}

C++ (@++)<!--
3
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
28 déc. 2007 à 16:48
Comme dit plus haut, acceptable venant d'un débutant mais totalement à refaire pour passer en prod.
Réfléchir à ce que fait strcat, tu verras que ce n'est pas productif dans une boucle.
ZeroMemory() est inutile si codé comme il se doit.
TOUJOURS vérifier les paramètres.


Autre version:


char *CentreTexte(char *Texte,int nmax)
{
  int len;
  char *d, *tampon = 0;
  len = strlen(Texte);
  if(!len) goto centrEXIT;
  len++;
  if(nmax < len) namx = len;
  tampon = (char*) malloc(nmax);
  if(!tampon) goto centrEXIT;
  d = tampon;
  nmax -= len;
  nmax /= 2;
  while(nmax) {
    *d++ = ' ';
    nmax--;
  }
  while(*d = *Texte) {d++; Texte++;}
 centrEXIT:
  return tampon;
}

ciao...
BruNews, MVP VC++
3
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
29 déc. 2007 à 05:45
&tampon
Pas nécessaire, simplement à passer tampon directement.
CentreTexte(TableNomMenu2[compteur],tampon,24);

C++ (@++)<!--
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
matonzo Messages postés 3 Date d'inscription mercredi 24 octobre 2007 Statut Membre Dernière intervention 28 décembre 2007
28 déc. 2007 à 15:48
Salut

Pour commencer, mettre des instructions après un return ça ne sert à rien car elle ne seront pas exécutées.

Ensuite, en admettant que tu veuilles faire ton free(tampon) avant le return,  il ne faut pas faire de free sur le pointeur retourné par ta fonction sinon quand tu essaieras d'accéder à la valeur retournée tu auras une belle erreur de segmentation.

Sinon, tu peut être un peu plus spécifique sur ton problème? ça ne fait pas ce que tu veux, ça ne compile pas, ça plante?...
0
cs_darunia Messages postés 354 Date d'inscription mercredi 18 décembre 2002 Statut Membre Dernière intervention 24 mars 2011 2
28 déc. 2007 à 15:51
Salut,

Boulette au niveau du free ! En effet tu fais ton return juste avant, et comme les instructions qui suivent le return ne sont pas executées (vu que le return rend la main a l'appelant), ton free ne sera jamais executé !

Autre truc, toujours verifier le retour d'un malloc (ça peut arriver qu'il renvoi null).

Et le ZeroMemory n'est pas bon, tu dois passer sizeof(char) * nbCaractereMax + 1 pour la longueur (imagine un systeme ou un char ferait plus d'1 octets)

Voila, a part pour le free qui est quand meme assez embetant, le code est correct pour un debutant !!!

D@runia
0
cs_darunia Messages postés 354 Date d'inscription mercredi 18 décembre 2002 Statut Membre Dernière intervention 24 mars 2011 2
28 déc. 2007 à 16:32
Oui je sais bien, mais on peut toujours imaginer !

D@runia
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
28 déc. 2007 à 17:34
Bizarre.
Quand je regarde le listing de nos code optimisé, le compilo transforme mon
while(c < calcul) *c++ = ' ';
et ton
while(nmax) {
    *d++ = ' ';
    nmax--;
  }
en un appel à memset...

C++ (@++)<!--
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
28 déc. 2007 à 17:51
Rien de bizarre, que de l'habituel. Quand il reconnait la signature ou plutot l'implem de memset, il fait cela à tout coup.

On s'en aperçoit de suite quand on bosse sans CRT, on a un message d'alerte dans la fenetre de compilation. En ce cas, je vire le memset en codant inversé: 'if' avant et 'do while' ainsi il me lache la grappe (le code voulais-je dire).

ciao...
BruNews, MVP VC++
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
28 déc. 2007 à 18:06
Bien vue.
Je trouve ça quand même stupide de remplacer une opération sur des pointeurs par un couteux appel à une fonction que l'on ne veut pas simplement parce que "ça y ressemble".
Est-il possible de désactiver complètement cette "fonctionnalité" ?

C++ (@++)<!--
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
28 déc. 2007 à 18:36
Aucune idée, mettre if devant et pousser le while en bas coute si peu que je n'ai jamais perdu de temps à chercher.

ciao...
BruNews, MVP VC++
0
PADYVEN Messages postés 69 Date d'inscription lundi 10 février 2003 Statut Membre Dernière intervention 29 août 2012
29 déc. 2007 à 05:20
Rebonjour et d'abord merci


BruNew dans ton exemple reecrit ne doit tu pas libere le malloc a un moment donné
sinon j'ai repri le code pour le transformer comme suivant

void CentreTexte(char *Texte, char *tampon, int nbCaractereMax)
{
    char *c = tampon;
    int len = strlen(Texte);


    if (nbCaractereMax > len)
    {
        int calcul = ((nbCaractereMax-len)/2)+(int)c;
        while(c < (char*)calcul) *c++ = ' ';
    }
    strcpy(c,Texte);
}

ce qui ce passe c'est que j'affiche un menu vertical avec texteout et les items de mon menu font au max 24characteres


comme vous l'avez compris je veux juste ajouter des espaces devant pour centrer les items de mon menu
la declaration de mon menu:
char *TableNomMenu2[9]={"Créer les liens","Configurer les cellules","Interconnecter","Effacer les liens","Effacer les configs","Effacer tous les liens","Effacer ttes les Configs","Tout effacer","Configurer"};

l'utilisation
char tampon[24]={0};
 CentreTexte(TableNomMenu2[compteur],(char *)&tampon,24);
 SetTextColor(hdc,0x0);
 TextOut(hdc,pos.x,pos.y,tampon,strlen(tampon));

est ce que tout est correct cette fois????????
encore merci
0
PADYVEN Messages postés 69 Date d'inscription lundi 10 février 2003 Statut Membre Dernière intervention 29 août 2012
29 déc. 2007 à 06:29
Merci a tous


a +


 
0
Rejoignez-nous