我有一个配置文件:
#X,Name,hostid,processid,executecommand,Max Runs, Max failure time
X,Main_XYZ_service,1,1,/opt/bada/bin,3,6,300
我解析了上面的配置文件,并将每个值存储在string类型的向量中。
这存储在vector<string> scanned
:
//scanned[0]=X
//scanned[1]=Main_XYZ_service.........
long H_hostid = atoi(scanned[5].c_str());
如何检测向量中存在的元素类型?
如果我使用没有数字的字符串调用atoi()
,atoi()
会返回0
,但如果字符串包含数字{{},则返回0
{1}}。如何正确地将值分配给0
?
答案 0 :(得分:1)
从绝对意义上说,你做不到。如果你遇到字符串“0”,你
无法知道用户是想要字符串,整数还是浮点数
点值。另一方面,如果你知道你需要什么,你可以试试
转换(例如使用boost::lexical_cast
),并生成错误
如果它不匹配。或者,您可以使用正则表达式
模式匹配,并决定你想要什么类型的结果
模式匹配。
对于配置文件,我建议使用前者。保持一切
作为一个字符串直到你知道你需要什么,然后尝试转换(使用
转换合理的东西,会报告错误,并且
不是atoi
)。
答案 1 :(得分:0)
不要使用atoi()
- 正如您所说,无法检测错误。在C ++中使用std::istringstream
,在C中使用strtol()
。
long H_hostid;
std::istringstream stream(scanned[5]);
if (!(stream >> H_hostid)) {
// handle error
}
您也可以使用boost::lexical_cast
,它与该示例的作用相同,如果转换失败则会抛出异常。
答案 2 :(得分:0)
如果这是存储为单个字符串的数据:
X,Main_XYZ_service,1,1,/opt/bada/bin,3,6,300
然后解决方案是,使用,
作为分隔符拆分此字符串,并将每个标记存储在大小为8
的数组中,然后您可以根据索引解释每个标记,如下所示: / p>
char,string, int, int, string, int, int, int
0 1 2 3 4 5 6 7
代码看起来像这样:
std::string s = "X,Main_XYZ_service,1,1,/opt/bada/bin,3,6,300";
std::vector<std::string> tokens = split(s); //write the function yourself!
char c = tokens[0]; //token with index 0 is char
std::string service = tokens[1]; //token with index 1 is string
std::string path = tokens[4]; //token with index 4 is string
int int_indices[] = {2,3,5,6,7}; //rest of the index has int : total 5
for(int i = 0 ; i < 5 ; i++ )
{
try
{
int value = boost::lexical_cast<int>(tokens[int_indices[i]]);
//store value
}
catch(const bad_lexical_cast &)
{
std::cout << tokens[int_indices[i]] <<" is not an int" << std::endl;
}
}
答案 3 :(得分:0)
每当您编写要由应用程序使用的配置文件时,您事先知道值将以何种顺序出现在该文件中。否则,对于一般情况,编写配置文件的xml或键值编码将是更好的选择。就个人而言,我永远不会像您在示例中所示创建配置文件。