2013-10-27 73 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)); 
    } 
} 
相关问题