2010-08-18 9 views
1

Je suis relativement nouveau en C++, venant du monde de Python. J'ai décidé d'écrire un ensemble de fonctions pour trouver la moyenne, la médiane, le mode et la gamme d'un ensemble de nombres. Pour aider au calcul de la médiane, j'ai décidé de faire 12g (le plus petit au plus grand) et g2l (le plus grand au moins). Je comprends que je n'utiliserai que l'un d'entre eux, mais je veux faire les deux juste pour l'exhaustivité.Comment obtenir un float à partir d'un char * en C++?

Je veux que mon programme utilise le moins de librairies externes (même standard). La raison en est que j'utiliserai probablement toutes les fonctions que j'écris à nouveau. Ils seront utilisés dans mon système d'exploitation que je développe basé sur les tutoriels de BrokenThorn. Par conséquent, je veux garder le code le plus indépendant possible, en utilisant des fonctions que j'écris à la place des fonctions dans les bibliothèques standard.

J'ai deux problèmes:

  • La première est que je veux que mes fonctions pour pouvoir gérer les valeurs flottantes. Avec la fonction d'entrée utilisateur que j'ai créée précédemment, j'obtiens un pointeur sur un tableau char. J'ai besoin de savoir comment convertir cela en une valeur flottante. Je pensais que je pourrais peut-être créer une union avec deux membres, de types char et float, et juste référence le membre flottant quand j'ai besoin d'utiliser la valeur. Je voudrais juste mettre des données d'utilisateur dans le membre char. Cependant, je ne sais pas si cette approche fonctionnerait. Le tutoriel que j'utilise ne va pas très loin dans la définition de mes propres types de données.
  • Mon second dilemme est que je ne sais pas comment créer les fonctions l2g et g2l. Je prévoyais d'emboîter deux pour les boucles. J'allais utiliser l'intérieur pour trouver le prochain numéro dans le nouveau tableau, et l'extérieur pour répéter ce processus jusqu'à ce qu'il passe à travers tous les nombres dans le tableau original. Ensuite, la fonction retournera un pointeur vers le nouveau tableau de flottants, après avoir supprimé la mémoire dynamique du premier tableau.

Un autre problème est que je pense que j'ai besoin de retourner la longueur d'un tableau lorsque je renvoie un pointeur. La raison en est que pour utiliser une boucle for pour parcourir le contenu de ce tableau, j'ai besoin d'avoir la position la plus haute utilisable dans le tableau, donc je ne reçois pas d'ordures. J'ai un moyen d'éviter ce problème en faisant une structure qui a deux membres, la longueur et le tableau. Il ressemble à ceci:

struct arrayLength { 
    int l; 
    float * p; 
} ; 

J'espérais que l'ensemble des appels suivants:

float * myArrayPointer; // I will change this to user input once I get the rest of the program working 
myArrayPointer = new float[5]; 
myArrayPointer[0] = 65.97; 
myArrayPointer[1] = 21.06; 
myArrayPointer[2] = 21.06; 
myArrayPointer[3] = 509.69; 
myArrayPointer[4] = -41.73; // Can floats be negative? 
cout << mean(myArrayPointer, 5); // Give function mean the pointer to array and number of elements 
cout << "\n"; 
cout << median(myArrayPointer, 5); 
cout << "\n"; 
cout << range(myArrayPointer, 5); 
cout << "\n"; 
cout << mode(myArrayPointer, 5); 
cout << "\n\n\n"; 
arrayLength myArrayPointerLG = l2g(myArrayPointer, 5); 
float * myArrayLGitem; 
for(int i=0;i<myArrayPointerLG.l;i++) { 
    myArrayLGitem = myArrayPointerLG.p[i]; 
    cout << myArrayPointerLGitem << "\n"; 
} 

donnerions la sortie suivante:

115.21 
21.06 
551.42 
21.06 

-41.73 
21.06 
21.06 
65.97 
509.69 

Jusqu'à présent, je n'ai pas obtenu mon code compilé. :/Je pense que peut-être une boucle for a sa propre portée ... Quelqu'un pourrait-il vérifier cela aussi? Voici un lien vers le code sur pastebin:

Pastebin

Et au cas où vous vous poseriez à propos de l'inclusion <iostream> ... Je vais retirer cela et utiliser les fonctions d'impression que j'ai écrit si je finis l'ajouter à mon système d'exploitation. OU je pourrais juste définir std :: cout. Les erreurs que j'obtiens disent que currentPosition et listOfNumbers sont non déclarés (non définis) dans l2g. Je cours Windows 7 64 bits, en utilisant le compilateur MSVC++ 2008 Express Edition. Merci d'avance à tous ceux qui aident!

+0

Votre code ne compile pas car il comporte d'importantes erreurs typographiques. - BTW, vous voulez éviter les fonctions de la bibliothèque, et vous utilisez 'new (nothrow)'? – UncleBens

+0

S'il vous plaît apprendre à utiliser les paragraphes. Votre message est presque illisible. En outre, utilisez des bibliothèques standard; ils sont entièrement portables. En outre, les flotteurs peuvent être négatifs. Les seuls types numériques qui ne peuvent pas être sont les types entiers non signés. –

+0

Pouvez-vous résumer certaines questions spécifiques (plus courtes)? Il est difficile d'analyser vos questions à partir de ce long article – Jay

Répondre

1

Si vous soulevez votre restriction sur l'utilisation bibliothèques, les deux tâches sont très simples.

La conversion de char * en float est facile avec Boost.lexical_cast (voir http://www.boost.org/doc/libs/1_43_0/libs/conversion/lexical_cast.htm). Il fournit des conversions de type sécurisé entre deux types, à condition qu'ils définissent les opérateurs "flux" (< < et >>).

#include "boost/lexical_cast.hpp" 
... 
const char* string_value = "1.5"; 
float float_value = boost::lexical_cast<float>(string_value); 

La méthode de tri de la bibliothèque standard est la méthode la plus simple pour commander votre baie. En utilisant votre exemple ci-dessus:

float * myArrayPointer; 
myArrayPointer = new float[5]; 
myArrayPointer[0] = 65.97; 
myArrayPointer[1] = 21.06; 
myArrayPointer[2] = 21.06; 
myArrayPointer[3] = 509.69; 
myArrayPointer[4] = -41.73; // Can floats be negative? 
std::sort(myArrayPointer, myArrayPointer+5); //Sort lowest to highest 
std::sort(myArrayPointer, myArrayPointer+5, std::greater<float>()); //Sort highest to lowest 

Si vous insistez pour le faire sans aucune aide de la bibliothèque, vous devrez mettre en œuvre un algorithme de tri pour vous-même. Il y a beaucoup à choisir, chacun vous donnant différentes caractéristiques de performance. Choisissez celui qui correspond le mieux à votre cas d'utilisation. Voir http://en.wikipedia.org/wiki/Sorting_algorithm pour beaucoup d'options. Quicksort et Merge-sort sont assez courants et donnent de très bonnes performances. En ce qui concerne la mise en œuvre manuelle des conversions char * à float, vous allez essentiellement implémenter le C de vous-même. Pour ce faire, vous devrez faire une boucle sur chaque caractère de la chaîne, le convertir en sa valeur intégrale correspondante et les accumuler dans un flottant. Vous utiliserez ensuite l'emplacement du point décimal pour déterminer comment mettre à l'échelle toutes les valeurs. Par exemple, pour convertir la chaîne "12.5" en float, vous devez convertir chaque caractère ('1', '2' et '5') en leurs entiers respectifs, et les mettre à l'échelle pour obtenir 1 * 10^1 + 2 * 10^0 + 5 * 10^-1. Il y a peut-être des façons plus efficaces de le faire, mais c'est aussi simple que je peux le faire.

+0

Merci! Cette réponse a beaucoup aidé. J'ai vu ailleurs sur le web un moyen de convertir un caractère en son entier respectif. Il a dit de simplement soustraire le caractère '0' du personnage à convertir. Exemple: c-'0 'retournerait cependant beaucoup plus haut que la valeur ASCII de c est supérieure à la valeur ASCII de zéro. Encore une fois, merci beaucoup pour la réponse. Cela a résolu mes problèmes. – masonsbro

6

a) apprendre à utiliser des conteneurs STL, algrithms etc ils vont rendre la vie beaucoup plus facile pour vous

b) c func atof fera ce que le titre de la question demande