Question

J'apprends actuellement le C ++ et j'ai décidé de créer un programme qui teste les compétences que j'ai acquises jusqu'à présent. Maintenant, dans mon code, je veux vérifier si la valeur entrée par l'utilisateur est un double, si ce n'est pas un double, je vais mettre une boucle if et leur demander de la ressaisir. Le problème que j'ai est de savoir comment vérifier le type de variable saisie par l'utilisateur. Par exemple, si un utilisateur entre un caractère ou une chaîne, je peux générer un message d'erreur. Voici mon code:

//cubes a user entered number
#include <iostream>
using namespace std;

double cube(double n); //function prototype

int main()
{
    cout << "Enter the number you want to cube: "; //ask user to input number
    double user;
    cin >> user;  //user entering the number

    cout << "The cube of " << user << " is " << cube(user) << "." << endl; //displaying the cubed number

    return 0;
}

double cube (double n) //function that cubes the number
{
    return n*n*n; // cubing the number and returning it
}

Edit: Je dois dire que je viens de commencer et que je n'ai aucune idée de votre code, mais je vérifierai votre lien. En passant, je n’ai pas encore appris à travailler avec des modèles, j’apprends à gérer les données, seul le chapitre 3 de la cinquième édition de C ++ Primer Plus.

Était-ce utile?

La solution

Il n'y a pas de moyen approprié de vérifier si une chaîne vraiment contient un double dans la bibliothèque standard. Vous voudrez probablement utiliser Boost . La solution suivante est inspirée de la recette 3.3 du livre de recettes C ++ :

#include <iostream>
#include <boost/lexical_cast.hpp>
using namespace std;
using namespace boost;

double cube(double n);

int main()
{
    while(true)
    {
        cout << "Enter the number you want to cube: ";
        string user;
        cin >> user;

        try
        {
            // The following instruction tries to parse a double from the 'user' string.
            // If the parsing fails, it raises an exception of type bad_lexical_cast.
            // If an exception is raised within a try{ } block, the execution proceeds
            // with one of the following catch() blocks
            double d = lexical_cast <double> (user);   

            cout << "The cube of " << d << " is " << cube(d) << "." << endl;
            break;
        }
        catch(bad_lexical_cast &e)
        {
            // This code is executed if the lexical_cast raised an exception; We
            // put an error message and continue with the loop
            cout << "The inserted string was not a valid double!" << endl;
        }
    }
    return 0;
}

double cube (double n)
{
    return n*n*n;
}

Autres conseils

Méthode de sécurité C ++

Vous pouvez définir une fonction pour cela en utilisant std :: istringstream :

#include <sstream>  

bool is_double(std::string const& str) {
    std::istringstream ss(str);

    // always keep the scope of variables as close as possible. we see
    // 'd' only within the following block.
    {
        double d;
        ss >> d;
    }

    /* eat up trailing whitespace if there was a double read, and ensure
     * there is no character left. the eof bit is set in the case that
     * `std::ws` tried to read beyond the stream. */
    return (ss && (ss >> std::ws).eof());
}

Pour vous aider à comprendre ce qu’il fait (certains points sont simplifiés):

  • Création d'un flux d'entrée-initialisé avec la chaîne donnée
  • Lecture d'une valeur double à l'aide de opérateur > > . Cela signifie ignorer les espaces et essayer de lire un double.
  • Si aucun double ne peut être lu, comme dans abc , le flux définit le bit fail . Notez que des cas tels que 3abc réussiront et ne ne définiront pas le bit d'échec.
  • Si le bit d'échec est défini, ss est évalué à zéro, ce qui signifie false .
  • Si un double a été lu, nous ignorons les espaces. Si nous sommes alors à la fin du flux (notez que eof () renverra true si nous essayons de lire après la fin. std: ws fait exactement cela), eof retournera true. Notez que cette vérification permet de s’assurer que 3abc ne passera pas notre vérification.
  • Si les deux cas, à droite et à gauche du & amp; & amp; sont évalués à true , nous retournons true à l'appelant, signalant que la chaîne donnée est un double.

Similaire, vous vérifiez int et d'autres types. Si vous savez travailler avec des modèles, vous savez aussi comment généraliser cela pour d'autres types. Incidemment, c’est exactement ce que boost :: lexical_cast vous fournit. Vérifiez-le: http://www.boost.org/ doc / libs / 1_37_0 / libs / conversion / lexical_cast.htm .

C Way One

Cette façon de procéder présente des avantages (rapidité) mais également des inconvénients majeurs (impossible de généraliser à l'aide d'un modèle, il est nécessaire de travailler avec des pointeurs bruts):

#include <cstdlib>
#include <cctype>  

bool is_double(std::string const& s) {
    char * endptr;
    std::strtod(s.c_str(), &endptr);
    if(endptr != s.c_str()) // skip trailing whitespace
        while(std::isspace(*endptr)) endptr++;
    return (endptr != s.c_str() && *endptr == '\0');
}

strtod définira endptr sur le dernier caractère traité. Ce qui est dans notre cas le caractère nul final. Si aucune conversion n'a été effectuée, endptr est défini sur la valeur de la chaîne attribuée à strtod .

Deuxième voie

On pourrait penser que std :: sscanf fait l'affaire. Mais il est facile de superviser quelque chose. Voici la bonne façon de le faire:

#include <cstdio>

bool is_double(std::string const& s) {
    int n;
    double d;
    return (std::sscanf(s.c_str(), "%lf %n", &d, &n) >= 1 && 
            n == static_cast<int>(s.size()));
}

std :: sscanf renverra les éléments convertis. Bien que la norme spécifie que % n ne soit pas inclus dans ce décompte, plusieurs sources se contredisent. Il est préférable de comparer > = pour bien faire les choses (voir la page de manuel de sscanf ). n sera défini sur la quantité de caractères traités. Il est comparé à la taille de la chaîne. L'espace entre les deux spécificateurs de format représente les espaces de fin facultatifs.

Conclusion

Si vous êtes débutant, lisez-le dans std :: stringstream et procédez de la manière C ++. Mieux vaut ne pas embêter les pointeurs tant que vous n'êtes pas satisfait du concept général de C ++.

sscanf peut faire ce que vous voulez. il retourne le nombre d'arguments correctement traités. Cela devrait vous aider à démarrer:

//cubes a user entered number
#include <iostream>
#include <cstdio>
using namespace std;

double cube(double n); //function prototype

int main()
{
        cout << "Enter the number you want to cube: "; //ask user to input number
        string user;
        cin >> user;  //user entering the number

        // Convert the number to a double.
        double value;
        if(sscanf(user.c_str(), "%lf", &value) != 1)
        {
                cout << "Bad!  " << user << " isn't a number!" << endl;
                return 1;
        }

        cout << "The cube of " << user << " is " << cube(user) << "." << endl; //displaying the cubed number

        return 0;
}

double cube (double n) //function that cubes the number
{
        return n*n*n; // cubing the number and returning it
}

Les autres méthodes publiées dans d'autres réponses ont leurs avantages et leurs inconvénients. Celui-ci a des problèmes avec les caractères de fin et n'est pas "C ++" -y.

Je dois dire que je viens de commencer et que je n'ai aucune idée de votre code, mais je vérifierai votre lien. En passant, je n’ai pas encore appris à travailler avec des modèles, j’apprends à gérer les données, seul le chapitre 3 de la cinquième édition de C ++ Primer Plus.

Vous pouvez utiliser C et utiliser strtod

Votre programme lit une chaîne, puis la transmet à une fonction qui tente de convertir la chaîne en double.

bool is_double(const char* strIn, double& dblOut) {
    char* lastConvert = NULL;
    double d = strtod(strIn, &lastConvert);
    if(lastConvert == strIn){
        return false;
    } else {
       dblOut = d;
       return true;
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top