Verifica tipo variável em C ++
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.
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 como3abc
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 que3abc
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;
}
}