Pergunta

Assim Atualmente, estou aprendendo C ++ e decidiu fazer um programa que testa minhas habilidades eu aprendi até agora. Agora no meu código eu quero verificar se o valor que o usuário digita é uma dupla, se não é um duplo porei se loop e pedir-lhes para digitá-la. O problema que tenho é como faço para ir sobre como verificar que tipo de variável que o usuário digita, ex- se um usuário digita um char ou string, eu pode produzir uma mensagem de erro. Aqui está o meu código:

//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: Eu teria que dizer que eu comecei e não têm a menor de idéia sobre seu código, mas vou verificar se o seu link. By the way, eu não aprendi como trabalhar com modelos ainda, eu estou aprendendo sobre como lidar com dados, apenas o capítulo 3 no meu C ++ Primer Plus 5ª edição.

Foi útil?

Solução

Não há nenhuma maneira apropriada para verificar se uma string realmente contém uma dupla dentro da biblioteca padrão. Você provavelmente vai querer usar impulso . A solução seguinte é inspirado por receita em 3,3 C ++ livro de receitas :

#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;
}

Outras dicas

Seguro C ++ Way

Você pode definir uma função para isso usando 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());
}

Para ajudá-lo a descobrir o que ele faz (alguns pontos são simplificados):

  • Criação de uma entrada de stringstream inicializado com a string dada
  • A leitura de um valor duplo fora dele usando operator>>. Isto significa ignorar espaços em branco e tentar ler um duplo.
  • Se nenhuma dupla poderia ser lido, como em abc o fluxo define o falha bits. Note-se que casos como 3abc terá sucesso e irá não definir o bits falhar.
  • Se o fail-bit é definido, avalia ss para um valor de zero, o que significa false .
  • Se um casal foi lido, vamos pular espaços em branco. Se, então, estão no final do fluxo (note que eof() irá retornar true se tentássemos ler além do fim. std::ws faz exatamente isso), eof retornará verdadeiro. Nota esta verificação garante que 3abc não vai passar o nosso check.
  • Se ambos os casos, direito e esquerdo do && avaliar a true , nós return true para o chamador, sinalizando a string dada é um duplo.

semelhante, você verificar se há int e outros tipos. Se você sabe como trabalhar com modelos, você sabe como generalizar isso para outros tipos também. Aliás, este é exatamente o que boost::lexical_cast fornece a você. Confira: http://www.boost.org/ doc / libs / 1_37_0 / libs / conversão / lexical_cast.htm .

C Way Um

Desta forma tem vantagens (sendo rápido), mas também grandes desvantagens (não pode generalizadas usando um modelo, necessidade de trabalhar com ponteiros crus):

#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 irá definir endptr para o último caractere processado. Que é no nosso caso o caractere nulo de terminação. Se nenhuma conversão foi realizada, endptr está definido para o valor da seqüência de caracteres determinada strtod.

C Way Two

Uma coisa poder que std::sscanf faz o truque. Mas é fácil para supervisionar alguma coisa. Aqui é a maneira correta de fazê-lo:

#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 vai devolver os itens convertidos. Embora especifica padrão que %n não está incluído nessa contagem, várias fontes se contradizem. É o melhor para comparar >= para obtê-lo direito (veja a página de manual de sscanf). n será definida como a quantidade dos caracteres processados. Ele é comparado com o tamanho da cadeia. O espaço entre os dois especificadores de formato é responsável por espaço em branco à direita opcional.

Conclusão

Se você é um novato, leia em std::stringstream e fazê-lo o caminho C ++. Melhor não mexer com ponteiros até que você se sentir bem com o conceito geral do C ++.

sscanf pode fazer o que quiser; ele retorna o número de argumentos devidamente processados. Isso deve começar:

//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
}

Outros métodos postados em outras respostas têm suas vantagens e desvantagens. Este tem problemas com caracteres à direita e não é "C ++" -. Y

Eu tenho que dizer que apenas começou e não tem a menor da pista sobre o seu código, mas vou verificar se o seu link. By the way, eu não aprendi como trabalhar com modelos ainda, eu estou aprendendo sobre como lidar com dados, apenas o capítulo 3 no meu C ++ Primer Plus 5ª edição.

Você pode cair para trás em C e usar strtod

Programa Você lê em uma corda e em seguida, passa para uma função que tenta converter a string em dupla.

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;
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top