Domanda

Sto cercando di scrivere un'istruzione if ma non riesco a trovare il modulo di espressione corretto da utilizzare. Sto pensando di scrivere qualcosa del genere:

if ( var != type(int) )

Tuttavia, non sono sicuro di come procedere e questo metodo non funziona.

Almeno sto pensando sulla retta linea?

È stato utile?

Soluzione

Sembra che tu stia provando a sovraccaricare una funzione:

void foo(int i)
{
    // stuff
}

void foo(float f)
{
    // stuff
}

int main(void)
{
    int i = 10;
    float f = 1.0f;

    foo(i); // calls foo(int)
    foo(f); // calls foo(float)
}

Se vuoi un comportamento speciale int e poi qualcos'altro in tutti gli altri casi, puoi usare i template:

template <typename T>
void foo(T t)
{
    // T is something
}

template <>
void foo(int i)
{
    // for int's only
}

int main(void)
{
    int i = 10;
    float f = 1.0f;
    double d = 2.0;

    foo(i); // calls specialized foo
    foo(f); // calls generic foo
    foo(d); // calls generic foo
}

Secondo il tuo commento ( " Il compito a portata di mano è un semplice programma: prendi due numeri interi immessi dall'utente e aggiungili. Limita l'input solo al numero intero. Posso farlo in Python e sto pensando anche in questo senso . se num1! = type (int): print " Non hai inserito un numero intero, inserisci un numero intero. " else: continua " ), vuoi qualcosa del genere:

#include <iostream>

int main(void)
{
    int i;
    std::cin >> i;

    if (std::cin.fail())
    {
        std::cout << "Not valid!" << std::endl;
    }
    else
    {
        // ...
    }
}

Questo notificherà input non validi come " @ # $ " ;, " r13 " ;, ma non rileva casi come " 34fg " ;, " 12 $ #% " , perché leggerà int e si fermerà a " fg " e " $ #% " ;, rispettivamente.

Per verificarlo, dovrai leggere una riga di input, quindi provare a convertire quella riga nel tipo che desideri. ( Grazie, litb ). Ciò significa che la tua domanda è più come questa domanda :

#include <iostream>
#include <sstream>
#include <string>

int main(void)
{
    std::string input;
    std::getline(std::cin, input);

    std::stringstream ss(input);
    int i;
    ss >> i;

    if (ss.fail() || !(ss >> std::ws).eof())
    {
        std::cout << "Not valid!" << std::endl;
    }
    else
    {
        // ...
    }
}

In questo modo: ottieni input e inseriscilo in un stringstream . Quindi, dopo aver analizzato int , esegui lo streaming di qualsiasi spazio bianco rimanente. Dopodiché, se eof è falso, significa che ci sono caratteri rimasti; l'input non è valido.

Questo è molto più facile da usare avvolto in una funzione. Nell'altra domanda, il cast è stato ripreso in considerazione; in questa domanda stiamo usando il cast, ma avvolgendo l'input con esso.

#include <iostream>
#include <sstream>
#include <string>

bool parse_int(int& i)
{
    std::string input;
    std::getline(std::cin, input);

    std::stringstream ss(input);
    ss >> i;

    return !(ss.fail() || !(ss >> std::ws).eof());
}

int main(void)
{
    int i;

    if (!parse_int(i))
    {
        std::cout << "Not valid!" << std::endl;
    }
    else
    {
        // ...
    }
}

O più genericamente:

#include <iostream>
#include <sstream>
#include <string>

template <typename T>
bool parse_type(T& t)
{
    std::string input;
    std::getline(std::cin, input);

    std::stringstream ss(input);
    ss >> t;

    return !(ss.fail() || !(ss >> std::ws).eof());
}

int main(void)
{
    int i;

    if (!parse_type(i))
    {
        std::cout << "Not valid!" << std::endl;
    }
    else
    {
        // ...
    }
}

Questo ti consente di analizzare altri tipi con controllo degli errori.


Se stai bene con le eccezioni, usando lexical_cast (o da boost, o " faked " ;, vedi l'altra domanda collegata nel codice [uguale al link sopra]), il tuo codice sarebbe assomigliare a questo:

#include <iostream>
#include <sstream>
#include <string>

/* Faked lexical-cast from question:
https://stackoverflow.com/questions/1243428/convert-string-to-int-with-bool-fail-in-c/
*/
template <typename T>
T lexical_cast(const std::string& s)
{
    std::stringstream ss(s);

    T result;
    if ((ss >> result).fail() || !(ss >> std::ws).eof())
    {
        throw std::bad_cast("Bad cast.");
    }

    return result;
}


template <typename T>
T parse_type(void)
{
    std::string input;
    std::getline(std::cin, input);

    return lexical_cast<T>(input);
}

int main(void)
{
    try
    {
        int i = parse_type<int>();
        float f = parse_type<float>();
    }
    catch (const std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
}

Non credo che boost abbia una versione no-throw del cast lessicale, quindi possiamo creare una versione true / false piuttosto che un'eccezione di questo codice catturando quelli di bad_cast , come segue. Ancora una volta, funziona con boost o con un cast lessicale personalizzato. (Tutto ciò che fa un cast lessicale e genera bad_cast ):

#include <iostream>
#include <sstream>
#include <string>

/* Faked lexical-cast from question:
https://stackoverflow.com/questions/1243428/convert-string-to-int-with-bool-fail-in-c/
*/
template <typename T>
T lexical_cast(const std::string& s)
{
    std::stringstream ss(s);

    T result;
    if ((ss >> result).fail() || !(ss >> std::ws).eof())
    {
        throw std::bad_cast("Bad cast.");
    }

    return result;
}


template <typename T>
bool parse_type(T& t)
{
    std::string input;
    std::getline(std::cin, input);

    try
    {
        t = lexical_cast<T>(input);

        return true;
    }
    catch (const std::bad_cast& e)
    {
        return false;
    }
}

int main(void)
{
    int i;
    if (!parse_type(i))
    {
        std::cout << "Bad cast." << std::endl;
    }
}

Ora è tornato al risultato bool , tranne per evitare la duplicazione del codice utilizzando le funzioni lexical_cast esistenti.

Puoi ovviamente scegliere quale metodo desideri utilizzare.

Altri suggerimenti

C ++ è un linguaggio tipicamente statico, il che significa che il tipo di variabile è sempre noto al compilatore. Per dichiarare quindi var , devi specificare un tipo per questo, che rende l'istruzione if che hai pubblicato un punto controverso. Se riesci a descrivere un po 'di più l'attività che stai cercando di svolgere, forse c'è un altro percorso per risolvere il tuo problema.

Esatto, sono necessarie ulteriori informazioni, se stai cercando un equivalente di " istanza di " operatore di Java, non ce n'è uno, a meno che tu non usi RTTI e typeid.

Vuoi dire che hai un valore in virgola mobile e vuoi sapere se è un numero intero o no?

In tal caso, prova questo:

#include <math.h>

//...

double x = 5.0;
if(round(x) == x) {
   // x has an integer value
}

Oppure, se il valore è il risultato di alcuni calcoli, potrebbero esserci piccoli errori di arrotondamento. Quindi prova qualcosa del genere:

double x = 4.99999999999;
if(abs(round(x) - x) < 1e-8)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top