Float from sting

cs_noumian Messages postés 49 Date d'inscription samedi 2 avril 2005 Statut Membre Dernière intervention 3 décembre 2008 - 4 mai 2007 à 22:40
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 - 6 mai 2007 à 16:43
bonjout a tous
j'ai un petit prebleme avec une fonction de mon programme
jvoudrais extraire un chiffre (float) inserer entre deux string "hello" et "world!" .le tout dans une string , par la fonction ci dessus:
float ExtractFloat(const char *str){

strcat("hello",str);

strcat("Word!",str);

return str;

 }

par exemple si je fait : c = ExtractFloat(

"Hello 1.124
World!");

'c' doit etre egale a 1.124

mais ca ne fonctionne pas aidez moi!!!

ouais man

11 réponses

DeAtHCrAsH Messages postés 2670 Date d'inscription vendredi 25 janvier 2002 Statut Membre Dernière intervention 6 février 2013
4 mai 2007 à 23:01
strcat ca sert a concatener non pas a extraire une chaine....
Parcours ta chaine octet par octet, puis dès que tu detecte le premier chiffre tu bufferise dans une variable temporaire.
Tu t'arretes une fois un caractère trouvé.
Ensuite pour convertir de char[] à float tu utilises atof(....).

Shell
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
4 mai 2007 à 23:03
atof() direct, aucun besoin de recopier.

ciao...
BruNews, MVP VC++
0
emmatopiak Messages postés 149 Date d'inscription mercredi 28 mars 2007 Statut Membre Dernière intervention 17 mai 2007 2
4 mai 2007 à 23:04
Salut,

Le premier appel doit être un strcpy et ensuite un strcat pas deux strcat.
Et puis c'est worLd pas word ( oublie pas l'espace )

@++
0
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
4 mai 2007 à 23:59
Salut,
Voici un petit exemple de fonction que tu peux améliorer:
float ExtractFloat(char* str)
{
    char chiffre=0;
    int index =0;
    do
    {
        chiffre=*(str+index);
        if(!chiffre) return 0; // = fin de la chaine
        index++;
    }while(!isdigit(chiffre));
    index--;
    return atof(str+index);
}
0

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

Posez votre question
DeAtHCrAsH Messages postés 2670 Date d'inscription vendredi 25 janvier 2002 Statut Membre Dernière intervention 6 février 2013
5 mai 2007 à 16:11
Voila un code identique a celui de racpp mais en plus performant et plus blindé.
- Controle de la validité du pointeur
- Gestion des rééls négatif
- Seule appel de atof (pas d'autre tel isdigit)
- Boucle while a la place de do..while pour éviter la décrémentation en fin de boucle
- Pas d'utilisation de variable char.

Voici le code :

float ExtractFloat(char * pszStr)
{
   int i = 0;

   if(!pszStr) return 0; // Test de la validité du pointeur
   while(!pszStr[i] && pszStr[i] < 47 || pszStr[i] > 58) i++; // Determine la position du premier digit

   if(i > 0 && pszStr[i-1] == 45) i--; // Gestion des rééls négatif   

   return atof(pszStr + i); // retourne le resultat après conversion en float
}

Shell
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
5 mai 2007 à 16:45
float ExtractFloat (char *str)
{
    char *c = str;
    if(!c) return 0;
    while(*c && (*c < '0' || *c > '9')) ++c;
    if(*c && *(c-1) == '-') --c;
    return atof(c);
}

C++ (@++)
0
DeAtHCrAsH Messages postés 2670 Date d'inscription vendredi 25 janvier 2002 Statut Membre Dernière intervention 6 février 2013
5 mai 2007 à 18:04
SAKingdom> C'etait bien pensé mais il y a un soucis avec une ligne de ton code ....

Quote : if(*c && *(c-1) == "-") --c;

Si tu as une chaine du genre 1.23Hello alors *(c-1) pointe sur une zone mémoire qui n'est pas tienne donc attention les dégats....
De plus le *c n'a aucun sens ici puisque au début tu vérifie la validité du pointeur qui a ce stade est focement bon meme dans le cas ou tu es en fin de chaine mais a ce moment la le test n'a pas lieu d'etre.

Shell
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
5 mai 2007 à 19:03
if(*c
On ne vérifie pas la validité du pointeur mais le contenue. Je test pour savoir si le caractère dans *c est nul. Si oui, inutile de comparer sont précédent car il n'y a plus rien après. On peut cependant s'arranger autrement
Pour le *(c-1) en dehors de la zone, oui c'est vrai, je n'y avait pas pensé mais il serait très étonnant que la valeur à cet endroit soit '-'. D'ailleurs, ça m'étonnerais beaucoup qu'il y ai des dégâts comme tu dit car il ne fait que lire.
Voici un model corrigé:
if(c !str && *(c-1) '-') --c; // atof s'arrangera si il y a un - en fin de chaine
ouif(*c && c !str && *(c-1) '-') --c; // atof s'arrangera si il s'agit du 0 de fin de chaine
ou encore
if(!*c) return 0; // Quitte direct s'il n'y a aucun chiffre dans la chaineelse if(c !str && *(c-1) '-') --c;

En passent, j'ai beaucoup de difficulté à comprend comment ton code pourrait bien fonctionner:
while(!pszStr[i] && pszStr[i] < 47 || pszStr[i] > 58) i++
Quitte sitôt qu'un caractère est non nul donc direct en début de chaine.

C++ (@++)
0
DeAtHCrAsH Messages postés 2670 Date d'inscription vendredi 25 janvier 2002 Statut Membre Dernière intervention 6 février 2013
5 mai 2007 à 21:54
lol reglement de compte ^^
Autant pour moi le signe "!" est de trop et des parenthèses sont manquantes.
Si mon code ne quitte actuellement pas c'est tout simplement à cause (ou grace) au "||".

Voici la correction de cette ligne :
while(pszStr[i] && (pszStr[i] < 47 || pszStr[i] > 58)) i++; // Determine la position du premier digit

Malgré tout ton code reste unsafe. Quand je te parle de dégat c'est surtout dans le sens ou tu ne maitrises pas cet emplacement mémoire et que donc tu n'es sur de rien. Si une personne prend ton algo et s'en sert dans de grosse boucle par exemple, elle risque d'avoir des surprises sans meme savoir pourquoi.
Le code unsafe est à bannir, tu fais du C pas du VB.

Bref ca fait toujours plaisir de partager des avis ;-)

Shell
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
5 mai 2007 à 22:25
"Le code unsafe est à bannir"

Dépend du point de vue. Quand l'on est seul maitre de ce qui se passe dans le programme (donc pas d'intervention de l'utilisateur), aucune raison de sécurité (par exemple, test de validité d'un pointeur). Mais sitôt que l'utilisateur entre en jeux, là faut tout prévoir. Quoi qu'il en soit, j'ai donné une version corrigé. Plus aucune raisons de bannir mon code:



float ExtractFloat (char *str)
{
    char *c = str;
    if(!c) return 0;
    while(*c && (*c < '0' || *c > '9')) ++c;
    if(!*c) return 0;    else if(c !str && *(c-1) '-') --c;
    return atof(c);
}

C++ (@++)
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
6 mai 2007 à 16:43
Bon aller je résiste pas:

#include <string>
#include <sstream>

std::string chaine("1456,54");
std::istringstream iss(chaine);

float value;
if ((iss >> value) && (iss.eof()))
{
// succes
std::cout << "Valeur : " << value << std::endl;
}
else
{
//echec
}
0
Rejoignez-nous