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);
ou bien je peux me contenter d'écrire
memcpy(ch, c, taille);
Toutes critiques sur la fonction seront les bienvenues.
Merci.
Alain CROS
#include <string.h>
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);
}
Alain CROS a écrit dans le message : 4333e995$0$17469$
Est ce nécessaire d'écrire memcpy(ch, c, sizeof(char) * taille); ou bien je peux me contenter d'écrire memcpy(ch, c, taille);
sizeof(char) vaut obligatoirement 1...
donc la 2eme propositions suffit...
Alain CROS
Bonjour.
"Stephane Legras-Decussy" a écrit dans le message de news: 4333f1ef$0$5425$ | > Est ce nécessaire d'écrire | > memcpy(ch, c, sizeof(char) * taille); | > ou bien je peux me contenter d'écrire | > memcpy(ch, c, taille); | | sizeof(char) vaut obligatoirement 1... | | donc la 2eme propositions suffit...
Si je comprends bien, que le char soit sur 7, 8, 9, ... bits, il correspond toujours a l'unité de base du système qui sera utilisé par memcpy et sizeof(char) sera toujours égale à 1.
Merci.
Alain CROS
J'ai corrigé un petit bug dans ma fonction et supprimé une variable.
#include <string.h>
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; char ch[taille + 1]; char *pch = ch; memcpy(ch, c, taille); ch[taille] = ' '; while(*pch != ' ') { if((*pch < '0') || (*pch > '9')) switch(*pch) { case ',': *pch = '.'; case '.': j = (j == 0) ? i : -1; break; default: j = -1; } if(j == -1) break; *pch++; i++; } if(j != -1) memcpy(c, ch, taille); return(j); }
Bonjour.
"Stephane Legras-Decussy" <admin@dtc.fr> a écrit dans le message de news: 4333f1ef$0$5425$626a14ce@news.free.fr...
| > Est ce nécessaire d'écrire
| > memcpy(ch, c, sizeof(char) * taille);
| > ou bien je peux me contenter d'écrire
| > memcpy(ch, c, taille);
|
| sizeof(char) vaut obligatoirement 1...
|
| donc la 2eme propositions suffit...
Si je comprends bien, que le char soit sur 7, 8, 9, ... bits, il correspond toujours a l'unité de base du système qui sera utilisé
par memcpy et sizeof(char) sera toujours égale à 1.
Merci.
Alain CROS
J'ai corrigé un petit bug dans ma fonction et supprimé une variable.
#include <string.h>
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;
char ch[taille + 1];
char *pch = ch;
memcpy(ch, c, taille);
ch[taille] = ' ';
while(*pch != ' ')
{
if((*pch < '0') || (*pch > '9'))
switch(*pch)
{
case ',':
*pch = '.';
case '.':
j = (j == 0) ? i : -1;
break;
default:
j = -1;
}
if(j == -1)
break;
*pch++;
i++;
}
if(j != -1)
memcpy(c, ch, taille);
return(j);
}
"Stephane Legras-Decussy" a écrit dans le message de news: 4333f1ef$0$5425$ | > Est ce nécessaire d'écrire | > memcpy(ch, c, sizeof(char) * taille); | > ou bien je peux me contenter d'écrire | > memcpy(ch, c, taille); | | sizeof(char) vaut obligatoirement 1... | | donc la 2eme propositions suffit...
Si je comprends bien, que le char soit sur 7, 8, 9, ... bits, il correspond toujours a l'unité de base du système qui sera utilisé par memcpy et sizeof(char) sera toujours égale à 1.
Merci.
Alain CROS
J'ai corrigé un petit bug dans ma fonction et supprimé une variable.
#include <string.h>
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; char ch[taille + 1]; char *pch = ch; memcpy(ch, c, taille); ch[taille] = ' '; while(*pch != ' ') { if((*pch < '0') || (*pch > '9')) switch(*pch) { case ',': *pch = '.'; case '.': j = (j == 0) ? i : -1; break; default: j = -1; } if(j == -1) break; *pch++; i++; } if(j != -1) memcpy(c, ch, taille); return(j); }
Harpo
Alain CROS wrote:
Bonjour.
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); ou bien je peux me contenter d'écrire memcpy(ch, c, taille);
Je l'espère...
Toutes critiques sur la fonction seront les bienvenues.
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).
En fait, il semble que ce soit -1 s'il existe dans la chaîne quelque chose qui n'est ni un chiffre ni un point. Je n'ai pas regardé vraiment en détail, cependant le truc avec i, j, k me semble touffu.
Il y a un moyen d'éviter de recopier la chaîne dans ch (surtout si elle ne doit comporter qu'une virgule), cela éviterait 2 memcpy( ) et ch deviendrait par là inutile. Bref, la fonction pourrait s'écrire plus simplement et plus lisiblement.
Alain CROS wrote:
Bonjour.
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);
ou bien je peux me contenter d'écrire
memcpy(ch, c, taille);
Je l'espère...
Toutes critiques sur la fonction seront les bienvenues.
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).
En fait, il semble que ce soit -1 s'il existe dans la chaîne quelque
chose qui n'est ni un chiffre ni un point.
Je n'ai pas regardé vraiment en détail, cependant le truc avec i, j, k
me semble touffu.
Il y a un moyen d'éviter de recopier la chaîne dans ch (surtout si elle
ne doit comporter qu'une virgule), cela éviterait 2 memcpy( ) et ch
deviendrait par là inutile.
Bref, la fonction pourrait s'écrire plus simplement et plus lisiblement.
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); ou bien je peux me contenter d'écrire memcpy(ch, c, taille);
Je l'espère...
Toutes critiques sur la fonction seront les bienvenues.
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).
En fait, il semble que ce soit -1 s'il existe dans la chaîne quelque chose qui n'est ni un chiffre ni un point. Je n'ai pas regardé vraiment en détail, cependant le truc avec i, j, k me semble touffu.
Il y a un moyen d'éviter de recopier la chaîne dans ch (surtout si elle ne doit comporter qu'une virgule), cela éviterait 2 memcpy( ) et ch deviendrait par là inutile. Bref, la fonction pourrait s'écrire plus simplement et plus lisiblement.
Marc Boyer
Le 23-09-2005, Alain CROS a écrit :
J'ai corrigé un petit bug dans ma fonction et supprimé une variable.
#include <string.h>
Allez, je suis pas le meilleur à ce jeu là, mais je tente.
int convstrnum(int taille, char *c)
bool convstrnum(size_t 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;
C'est quoi 'i' et 'j' ?
char ch[taille + 1];
Souvent une mauvaise idée: si on a pas la mémoire pour allouer taille+1, ben, ça va faire boum, et on a pas moyen de le savoir.
-- À vélo, prendre une rue à contre-sens est moins dangeureux que prendre un boulevard dans le sens légal. À qui la faute ?
Le 23-09-2005, Alain CROS <Personne@ICI> a écrit :
J'ai corrigé un petit bug dans ma fonction et supprimé une variable.
#include <string.h>
Allez, je suis pas le meilleur à ce jeu là, mais je tente.
int convstrnum(int taille, char *c)
bool convstrnum(size_t 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;
C'est quoi 'i' et 'j' ?
char ch[taille + 1];
Souvent une mauvaise idée: si on a pas la mémoire
pour allouer taille+1, ben, ça va faire boum, et on
a pas moyen de le savoir.
J'ai corrigé un petit bug dans ma fonction et supprimé une variable.
#include <string.h>
Allez, je suis pas le meilleur à ce jeu là, mais je tente.
int convstrnum(int taille, char *c)
bool convstrnum(size_t 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;
C'est quoi 'i' et 'j' ?
char ch[taille + 1];
Souvent une mauvaise idée: si on a pas la mémoire pour allouer taille+1, ben, ça va faire boum, et on a pas moyen de le savoir.
-- À vélo, prendre une rue à contre-sens est moins dangeureux que prendre un boulevard dans le sens légal. À qui la faute ?
Targeur fou
Alain CROS wrote:
Bonjour.
Bonjour,
J'ai écrit une fonction qui remplace la virgule par un point dans une c haine 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); ou bien je peux me contenter d'écrire memcpy(ch, c, taille);
sizeof(char) == 1 par définition, donc seconde forme pour moi. Ceci dit, si tu dois un jour copier avec memcpy() des données d'un autre type, utiliser sizeof(type)*taille est une bonne pratique, notamment avec les tableaux. Pour ne pas se tromper, utiliser l'opérateur sizeof sur la donnée elle-même (de type bien défini) plutôt que de passer un type n'est pas mal non plus. Je privilégie le premier cas si je travaille avec des tableaux, le second si je travaille avec des pointeurs, pas bien dur de voir le pourquoi. Si je travaille avec le type char, pointeur ou tableau, je ne précise que la taille.
Toutes critiques sur la fonction seront les bienvenues.
Merci.
Alain CROS
#include <string.h>
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];
Note : plus d'accolades avec les if ne ferait pas de mal. Je pense aussi que tu as un pointeur en trop (pch) : tupeux très bien sauvegarder la chaine à traiter, travailler directement dessus, puis la restaurer en cas de besoin.
int isCharValid(char c) { return ( (isdigit(c) || c == '.' || c == ',') ? 1 : 0 ); }
/** * comma2dot * Remplace la virgule par le point comme séparateur dans une chaine numérique * @param[in] s chaine à traiter * @return rc * 0 : succes * -1 : argument nul * -2 : pb allocation * -3 : chaine fournie non valide */ int comma2dot(char * s) { int rc = 0;
if (s != NULL) {
size_t lg = strlen(s); char * tmp = malloc(lg+1);
if (tmp != NULL) {
int cptDot = 0; memcpy(tmp, s, lg+1);
/* boucle de traitement */ /* on remplace toutes les virgules rencontrées par des points */ /* on se préoccuppera plus tard de la validité de la chaine */ /* avec le nb de points insérés */ while(*s != ' ') { if (isCharValid(*s)) { if (*s == '.') { ++cptDot; } if (*s == ',') { *s = '.'; ++cptDot; } } else { rc = -3; break; } ++s; }
/* plus de 1 separateur rencontres, ca va pas */ rc = (cptDot > 1) ? -3 : rc;
/* restauration de la chaine initiale si pas bon */ if (rc == -3) { memcpy(s, tmp, lg+1); }
free(tmp);
} else { rc = -2; } } else { rc = -1; }
return rc;
}
A+ Regis
Alain CROS wrote:
Bonjour.
Bonjour,
J'ai écrit une fonction qui remplace la virgule par un point dans une c haine 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);
ou bien je peux me contenter d'écrire
memcpy(ch, c, taille);
sizeof(char) == 1 par définition, donc seconde forme pour moi. Ceci
dit, si tu dois un jour copier avec memcpy() des données d'un autre
type, utiliser sizeof(type)*taille est une bonne pratique, notamment
avec les tableaux. Pour ne pas se tromper, utiliser l'opérateur sizeof
sur la donnée elle-même (de type bien défini) plutôt que de passer
un type n'est pas mal non plus. Je privilégie le premier cas si je
travaille avec des tableaux, le second si je travaille avec des
pointeurs, pas bien dur de voir le pourquoi. Si je travaille avec le
type char, pointeur ou tableau, je ne précise que la taille.
Toutes critiques sur la fonction seront les bienvenues.
Merci.
Alain CROS
#include <string.h>
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];
Note : plus d'accolades avec les if ne ferait pas de mal. Je pense
aussi que tu as un pointeur en trop (pch) : tupeux très bien
sauvegarder la chaine à traiter, travailler directement dessus, puis
la restaurer en cas de besoin.
int isCharValid(char c)
{
return ( (isdigit(c) || c == '.' || c == ',') ? 1 : 0 );
}
/**
* comma2dot
* Remplace la virgule par le point comme séparateur dans une chaine
numérique
* @param[in] s chaine à traiter
* @return rc
* 0 : succes
* -1 : argument nul
* -2 : pb allocation
* -3 : chaine fournie non valide
*/
int comma2dot(char * s)
{
int rc = 0;
if (s != NULL) {
size_t lg = strlen(s);
char * tmp = malloc(lg+1);
if (tmp != NULL) {
int cptDot = 0;
memcpy(tmp, s, lg+1);
/* boucle de traitement */
/* on remplace toutes les virgules rencontrées par des
points */
/* on se préoccuppera plus tard de la validité de la
chaine */
/* avec le nb de points insérés */
while(*s != ' ') {
if (isCharValid(*s)) {
if (*s == '.') { ++cptDot; }
if (*s == ',') { *s = '.'; ++cptDot; }
}
else {
rc = -3;
break;
}
++s;
}
/* plus de 1 separateur rencontres, ca va pas */
rc = (cptDot > 1) ? -3 : rc;
/* restauration de la chaine initiale si pas bon */
if (rc == -3) {
memcpy(s, tmp, lg+1);
}
J'ai écrit une fonction qui remplace la virgule par un point dans une c haine 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); ou bien je peux me contenter d'écrire memcpy(ch, c, taille);
sizeof(char) == 1 par définition, donc seconde forme pour moi. Ceci dit, si tu dois un jour copier avec memcpy() des données d'un autre type, utiliser sizeof(type)*taille est une bonne pratique, notamment avec les tableaux. Pour ne pas se tromper, utiliser l'opérateur sizeof sur la donnée elle-même (de type bien défini) plutôt que de passer un type n'est pas mal non plus. Je privilégie le premier cas si je travaille avec des tableaux, le second si je travaille avec des pointeurs, pas bien dur de voir le pourquoi. Si je travaille avec le type char, pointeur ou tableau, je ne précise que la taille.
Toutes critiques sur la fonction seront les bienvenues.
Merci.
Alain CROS
#include <string.h>
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];
Note : plus d'accolades avec les if ne ferait pas de mal. Je pense aussi que tu as un pointeur en trop (pch) : tupeux très bien sauvegarder la chaine à traiter, travailler directement dessus, puis la restaurer en cas de besoin.
int isCharValid(char c) { return ( (isdigit(c) || c == '.' || c == ',') ? 1 : 0 ); }
/** * comma2dot * Remplace la virgule par le point comme séparateur dans une chaine numérique * @param[in] s chaine à traiter * @return rc * 0 : succes * -1 : argument nul * -2 : pb allocation * -3 : chaine fournie non valide */ int comma2dot(char * s) { int rc = 0;
if (s != NULL) {
size_t lg = strlen(s); char * tmp = malloc(lg+1);
if (tmp != NULL) {
int cptDot = 0; memcpy(tmp, s, lg+1);
/* boucle de traitement */ /* on remplace toutes les virgules rencontrées par des points */ /* on se préoccuppera plus tard de la validité de la chaine */ /* avec le nb de points insérés */ while(*s != ' ') { if (isCharValid(*s)) { if (*s == '.') { ++cptDot; } if (*s == ',') { *s = '.'; ++cptDot; } } else { rc = -3; break; } ++s; }
/* plus de 1 separateur rencontres, ca va pas */ rc = (cptDot > 1) ? -3 : rc;
/* restauration de la chaine initiale si pas bon */ if (rc == -3) { memcpy(s, tmp, lg+1); }
free(tmp);
} else { rc = -2; } } else { rc = -1; }
return rc;
}
A+ Regis
Alain CROS
Bonjour.
Merci pour les nombreuses réponses. J'analyse tous ça pour essayer d'en tirer de bonnes pratiques.
Alain CROS
Bonjour.
Merci pour les nombreuses réponses.
J'analyse tous ça pour essayer d'en tirer de bonnes pratiques.
car si on change le type de '* arr1' en disons triple, il n'est pas nécessaire de changer cette instruction.
Emmanuel Delahaye
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() ?
#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] = ' '; while (*pch != ' ') { 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
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() ?
#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] = ' ';
while (*pch != ' ')
{
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
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() ?
#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] = ' '; while (*pch != ' ') { 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
Emmanuel Delahaye
Alain CROS wrote on 23/09/05 :
J'ai corrigé un petit bug dans ma fonction et supprimé une variable.
Ne traite toujours pas les nombres négatifs...
-- Emmanuel The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html The C-library: http://www.dinkumware.com/refxc.html
I once asked an expert COBOL programmer, how to declare local variables in COBOL, the reply was: "what is a local variable?"
Alain CROS wrote on 23/09/05 :
J'ai corrigé un petit bug dans ma fonction et supprimé une variable.
Ne traite toujours pas les nombres négatifs...
--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html
I once asked an expert COBOL programmer, how to
declare local variables in COBOL, the reply was:
"what is a local variable?"
int isCharValid(char c) { return ( (isdigit(c) || c == '.' || c == ',') ? 1 : 0 );
COmpliqué...
return (isdigit(c) || c == '.' || c == ',');
}
/** * comma2dot * Remplace la virgule par le point comme séparateur dans une chaine numérique * @param[in] s chaine à traiter * @return rc * 0 : succes * -1 : argument nul * -2 : pb allocation * -3 : chaine fournie non valide */ int comma2dot(char * s) { int rc = 0;
if (s != NULL) {
size_t lg = strlen(s); char * tmp = malloc(lg+1);
Ca fout la trouille!
-- Emmanuel The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html The C-library: http://www.dinkumware.com/refxc.html
int isCharValid(char c)
{
return ( (isdigit(c) || c == '.' || c == ',') ? 1 : 0 );
COmpliqué...
return (isdigit(c) || c == '.' || c == ',');
}
/**
* comma2dot
* Remplace la virgule par le point comme séparateur dans une chaine
numérique
* @param[in] s chaine à traiter
* @return rc
* 0 : succes
* -1 : argument nul
* -2 : pb allocation
* -3 : chaine fournie non valide
*/
int comma2dot(char * s)
{
int rc = 0;
if (s != NULL) {
size_t lg = strlen(s);
char * tmp = malloc(lg+1);
Ca fout la trouille!
--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html
int isCharValid(char c) { return ( (isdigit(c) || c == '.' || c == ',') ? 1 : 0 );
COmpliqué...
return (isdigit(c) || c == '.' || c == ',');
}
/** * comma2dot * Remplace la virgule par le point comme séparateur dans une chaine numérique * @param[in] s chaine à traiter * @return rc * 0 : succes * -1 : argument nul * -2 : pb allocation * -3 : chaine fournie non valide */ int comma2dot(char * s) { int rc = 0;
if (s != NULL) {
size_t lg = strlen(s); char * tmp = malloc(lg+1);
Ca fout la trouille!
-- Emmanuel The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html The C-library: http://www.dinkumware.com/refxc.html