2013-10-27 123 views
2

我是一位來自Java的C++新手,所以我需要一些關於我在我遇到的基本問題時遇到的一些基本問題的指導。C++檢測輸入是Int還是String

我正在讀取文件中的行,每行包含6個字符串/整數,它們將作爲參數發送到臨時變量。

實施例:

Local1,Local2,ABC,200,300,asphalt 

然而,有可變的兩個亞型。其中一個字符串作爲最後一個參數(如上例中的「瀝青」)。另一個有一個int。我有一個方法讀取每個參數並將其發送給變量,但是如何預先檢測字符串的最後一位是整數還是字符串,因此我知道是否應將它發送到Type1變量或Type2變量?

非常感謝!

+2

這就是*解析*的全部內容... –

+2

你會如何在java中做到這一點? – atk

+0

我的不好,我忘記從我解決之前的另一個問題中改變它,現在已經修復 – Jaqualembo

回答

2

既然你想確定最後一列的類型,那麼這應該工作:

#include <iostream> 
#include <string> 
#include <cstdlib> 
#include <vector> 
#include <sstream> 
#include <cctype> 
#include <algorithm> 

enum Types { 
    NONE, 
    STRING, 
    INTEGER, 
    DOUBLE 
}; 

struct Found { 
    std::string string_val; 
    int integer_val; 
    double double_val; 
    enum Types type; 
}; 

//copied verbatim from: 
//http://stackoverflow.com/a/2845275/866930 
inline bool isInteger(const std::string &s) { 
    if(s.empty() || ((!std::isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false; 

    char * p ; 
    std::strtol(s.c_str(), &p, 10); 

    return (*p == 0); 
} 

//modified slightly for decimals: 
inline bool isDouble(const std::string &s) { 
    if(s.empty() || ((!std::isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false ; 

    char * p ; 
    std::strtod(s.c_str(), &p) ; 

    return (*p == 0); 
} 

bool isNotAlpha(char c) { 
    return !(std::isalpha(c)); 
} 

//note: this searches for strings containing only characters from the alphabet 
//however, you can modify that behavior yourself. 
bool isString (const std::string &s) { 
    std::string::const_iterator it = std::find_if(s.begin(), s.end(), isNotAlpha); 
    return (it == s.end()) ? true : false; 
} 

void determine_last_column (const std::string& str, Found& found) { 
    //reset found: 
    found.integer_val = 0; 
    found.double_val = 0; 
    found.string_val = ""; 
    found.type = NONE; 

    std::string temp; 
    std::istringstream iss(str); 

    int column = 0; 
    char *p; 

    while(std::getline(iss, temp, ',')) { 
     if (column == 5) { 
      //now check to see if the column is an integer or not: 
      if (isInteger(temp)) { 
       found.integer_val = static_cast<int>(std::strtol(temp.c_str(), &p, 10)); 
       found.type = INTEGER; 
      } 
      else if (isDouble(temp)) { 
       found.double_val = static_cast<double>(std::strtod(temp.c_str(), &p)); 
       found.type = DOUBLE; 
      } 
      else if (isString(temp)) { 
       found.string_val = temp; 
       found.type = STRING; 
      } 
     } 
     ++column; 
    } 

    if (found.type == INTEGER) { 
     std::cout << "An integer was found: " << found.integer_val << std::endl; 
    } 
    else if(found.type == DOUBLE) { 
     std::cout << "A double was found: " << found.double_val << std::endl; 
    } 
    else if(found.type == STRING) { 
     std::cout << "A string was found: " << found.string_val << std::endl; 
    } 
    else { 
     std::cout << "A valid type was not found! Something went wrong..." << std::endl; 
    } 
} 

int main() { 
    std::string line_t1 = "Local1,Local2,ABC,200,300,asphalt"; 
    std::string line_t2 = "Local1,Local2,ABC,200,300,-7000.3"; 

    Found found; 

    determine_last_column(line_t1, found); 
    determine_last_column(line_t2, found); 

    return 0; 
} 

此輸出和正確地分配適當的值:

A string was found: asphalt 
An integer was found: -7000.3 

此版本適用於int, double, string; 不需要boost;並且,是普通的香草C++ 98。

參考:

UPDATE:

現在這個版本支持這兩個是整數或雙打,除了字符串正數和負數。

+0

非常感謝您的出色投入,我希望這確實能解決,我相信它應該。還有一個問題,這將使用雙精度而不是整數嗎?主要是關於'isdigit'。 – Jaqualembo

+0

@Jaqualembo:更新。 – jrd1

+0

我設法通過調整您提供的一些代碼來使其工作。再次非常感謝 – Jaqualembo

1

首先,創建一個可以存儲字符串和整數數組:

std::vector<boost::variant<std::string, int>> items; 

二,拆分輸入的逗號字符串:

std::vector<std::string> strings; 
boost::split(strings, input, boost::is_any_of(",")); 

最後,分析每個令牌,並將其插入到array:

for (auto&& string : strings) { 
    try { 
     items.push_back(boost::lexical_cast<int>(string)); 
    } catch(boost::bad_lexical_cast const&) { 
     items.push_back(std::move(string)); 
    } 
} 
相關問題