簡體   English   中英

在C ++中檢查變量類型

[英]Check variable type in C++

所以我目前正在學習C ++,並決定制作一個測試我迄今為止學到的技能的程序。 現在在我的代碼中我想檢查用戶輸入的值是否為double,如果它不是double,我將放置if循環並要求它們重新輸入。 我遇到的問題是如何檢查用戶輸入的變量類型,如果用戶輸入字符或字符串,我可以輸出錯誤消息。 這是我的代碼:

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

編輯:我不得不說我剛開始並且對你的代碼沒有絲毫的線索,但我會查看你的鏈接。 順便說一句,我還沒有學習如何使用模板,我正在學習如何處理數據,只有我的C ++ Primer Plus第5版第3章。

安全的C ++方式

您可以使用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());
}

為了幫助您弄清楚它的作用(簡化了一些要點):

  • 創建一個用給定字符串初始化的輸入字符串流
  • 使用operator>>從中讀取double值。 這意味着跳過空格並嘗試讀取雙精度數。
  • 如果不能讀取雙abc ,則在abc中流設置失敗位。 請注意,像3abc這樣的情況會成功,並且不會設置失敗位。
  • 如果設置了失敗位,則ss計算為零值,這意味着為false
  • 如果讀取了double,我們會跳過尾隨空格。 然后如果我們是在流結束(注意, eof()如果我們試圖讀取過去的結束將返回true。 std::ws正是這么做的), eof將返回true。 請注意,此檢查確保3abc不會通過我們的檢查。
  • 如果&&兩個情況,右邊和左邊的值都為true ,我們返回true給調用者,表示給定的字符串是double。

類似的,你檢查int和其他類型。 如果您知道如何使用模板,那么您也知道如何將其概括為其他類型。 順便說一句,這正是boost::lexical_cast為您提供的。 請查看: http//www.boost.org/doc/libs/1_37_0/libs/conversion/lexical_cast.htm

C Way One

這種方式有優點(快速)但也有主要缺點(不能使用模板推廣,需要使用原始指針):

#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會將endptr設置為最后處理的字符。 在我們的例子中,終止空字符。 如果未執行轉換,則將endptr設置為給予strtod的字符串的值。

C方式二

一個可能是std::sscanf事情。 但是監督某些事情很容易。 這是正確的方法:

#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將返回轉換的項目。 雖然標准規定%n不包括在該計數中,但是幾個來源相互矛盾。 最好比較>=以使其正確(參見sscanf的聯機幫助頁)。 n將被設置為已處理字符的數量。 它與字符串的大小進行比較。 兩個格式說明符之間的空格占可選的尾部空格。

結論

如果您是初學者,請閱讀std::stringstream並以C ++方式進行操作。 在你對C ++的一般概念感覺良好之前,最好不要亂用指針。

沒有合適的方法來檢查字符串是否真的包含標准庫中的double。 您可能想要使用Boost 以下解決方案的靈感來自C ++ Cookbook中的配方3.3:

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

sscanf可以做你想做的事; 它返回正確處理的參數數量。 這應該讓你開始:

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

其他答案中公布的其他方法各有優缺點。 這個問題有尾隨字符而不是“C ++” - y。

我不得不說我剛開始並且對你的代碼沒有絲毫的線索,但我會查看你的鏈接。 順便說一句,我還沒有學習如何使用模板,我正在學習如何處理數據,只有我的C ++ Primer Plus第5版第3章。

你可以退回到C並使用strtod

您編程讀取字符串,然后將其傳遞給嘗試將字符串轉換為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;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM