🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: fr.comp.lang.c
Article #15498

Re: memcpy et char

#15498
From: Emmanuel Delahaye
Date: Fri, 23 Sep 2005 15:35
205 lines
5563 bytes
Alain CROS wrote on 23/09/05 :
> J'ai �crit une fonction qui remplace la virgule par un point dans une chaine 
> de caract�res pour ensuite permettre de faire un calcul.
> Pour copier une chaine dans une autre chaine, j'utilise memcpy.
> Est ce n�cessaire d'�crire
>     memcpy(ch, c, sizeof(char) * taille);

Redondance inutile. Par contre

     memcpy(ch, c, sizeof *ch * taille);

si le type est appel� � changer (char -> wchar_t, par exemple) et que 
la taille est un nombre d'�l�ments...

> ou bien je peux me contenter d'�crire
>     memcpy(ch, c, taille);

Oui, ou mieux

memcpy(ch, c, sizeof ch);

si ch est un tableau. Evidemment, si c'est un pointeur, il vaut mieux 
oublier (pas dangereux, mais s�rieusement limit�...)

> #include <string.h>
>
> int convstrnum(int taille, char *c)

La chaine initiale est donc modifiable. Je recommande size_t pour la 
taille. Si 'c' est l'adresse d'une chaine conforme, � quoi sert la 
taille ?

> /*  Remplace, dans une chaine de caract�res repr�sentant un chiffre,
>         la virgule par un point.
>     Retourne :
>         la position de ce point dans la chaine (base 1).
>         0 si pas de point.
>         -1 si pas un chiffre (la chaine reste inchang�e).
> */
> {
>     int i = 1, j = 0, k = 0;

Je recommande size_t pour i.

>     char ch[taille + 1];

[C99] VLA ? Je ne connais pas d'impl�mentation conforme. Qu'est-ce qui 
ne va pas avec malloc() ?

>     char *pch = ch;
>     memcpy(ch, c, sizeof(char) * taille);
>     ch[taille] = '\0';

S�curit� ?

>     while(*pch != '\0')
>     {
>         if((*pch < '0') || (*pch > '9'))
>             switch(*pch)
>             {
>                 case '.':
>                     j = (++k == 2) ? -1 : j;
>                     break;
>                 case ',':
>                     *pch-- = '.';
>                     j = i--;
>                     break;
>                 default:
>                     j = -1;
>             }
>         if(j == -1)
>             break;
>         *pch++;
>         i++;
>     }
>     if(j != -1)
>         memcpy(c, ch, sizeof(char) * taille);
>     return(j);
> }

Ca me parait hyper compliqu�! Si la chaine initiale est modifiable, il 
suffit de la modifier directement.

#include <string.h>
#include <stdio.h>
#include <ctype.h>

/* 0 | 1 */
#define ED 0

#if !ED
static int convstrnum (int taille, char *c)
/*  Remplace, dans une chaine de caract�res repr�sentant un chiffre,
   la virgule par un point.
   Retourne :
   la position de ce point dans la chaine (base 1).
   0 si pas de point.
   -1 si pas un chiffre (la chaine reste inchang�e).
 */
{
   int i = 1, j = 0, k = 0;
   char ch[taille + 1];
   char *pch = ch;
   memcpy (ch, c, sizeof (char) * taille);
   ch[taille] = '\0';
   while (*pch != '\0')
   {
      if ((*pch < '0') || (*pch > '9'))
         switch (*pch)
         {
         case '.':
            j = (++k == 2) ? -1 : j;
            break;
         case ',':
            *pch-- = '.';
            j = i--;
            break;
         default:
            j = -1;
         }
      if (j == -1)
         break;
      *pch++;
      i++;
   }
   if (j != -1)
      memcpy (c, ch, sizeof (char) * taille);
   return (j);
}
#else
/*  Remplace, dans une chaine de caract�res repr�sentant un nombre,
   la virgule par un point.
   Retourne :
   la position de ce point dans la chaine (base 1).
   0 si pas de point.
   -1 si pas un nombre (la chaine reste inchang�e).
 */
static int convstrnum (char *c)
{
   int n = -1;
   char *p = c;

   while (*p != 0)
   {
      if (n == -1)
      {
         if (isdigit (*p) || *p == '-')
         {
            n = 0;
         }
         else
         {
            break;
         }
      }
      else
      {
         if (*p == ',')
         {
            *p = '.';
            n = (int) (p - c) + 1;
         }
      }

      p++;
   }
   return n;
}
#endif

int main (void)
{
   char as[][32] =
   {
      "",
      "abc",
      "123",
      "-123",
      "123,456",
      "-123,456",
   };
   size_t i;

   for (i = 0; i < sizeof as / sizeof *as; i++)
   {
      char *s = as[i];
      printf ("'%s' -> ", s);
      {
#if !ED
         int n = convstrnum ((int) strlen (s), s);
#else
         int n = convstrnum (s);
#endif
         printf ("'%s' (%d)\n", s, n);
      }
   }
   return 0;
}

-- 
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

.sig under repair
Technical Details
Message-ID: <mn.bc1f7d598a134f88.15512@YOURBRAnoos.fr>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!news.glorb.com!proxad.net!infeed-3.proxad.net!news18-e.free.fr!not-for-mail
References: <4333e995$0$17469$626a14ce@news.free.fr>

Show Full Headers
Complete Article Headers
X-Google-Thread: f9822,366ad66ae342f8da
X-Google-Attributes: gidf9822,public
X-Google-Language: FRENCH,ASCII
Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!news.glorb.com!proxad.net!infeed-3.proxad.net!news18-e.free.fr!not-for-mail
Subject: Re: memcpy et char
From: "Emmanuel Delahaye" <emdel@YOURBRAnoos.fr>
References: <4333e995$0$17469$626a14ce@news.free.fr>
Newsgroups: fr.comp.lang.c
Message-ID: <mn.bc1f7d598a134f88.15512@YOURBRAnoos.fr>
X-Newsreader: MesNews/1.04.00.00-fr
Date: Fri, 23 Sep 2005 17:35:20 +0200
MIME-Version: 1.0
Content-Type: text/plain; charset="iso-8859-15"; format=flowed
Content-Transfer-Encoding: 8bit
Lines: 207
Organization: Guest of ProXad - France
NNTP-Posting-Date: 23 Sep 2005 17:35:21 MEST
NNTP-Posting-Host: 81.65.109.78
X-Trace: 1127489721 news18-e.free.fr 18840 81.65.109.78:16418
X-Complaints-To: abuse@proxad.net