有没有办法读取这样格式化的字符串,比如说::48754+7812=Abcs
。
假设我有三个字符串 X、Y 和 Z,我想
X = 48754
Y = 7812
Z = Abcs
这两个数字的大小和字符串的长度可能会有所不同,因此我不想使用substring()
或类似的函数。
是否可能在C++中传递这样的参数?
":#####..+####..=SSS.."
所以它直接知道发生了什么?
#include <iostream>
#include <sstream>
int main(int argc, char **argv) {
std::string str = ":12341+414112=absca";
std::stringstream ss(str);
int v1, v2;
char col, op, eq;
std::string var;
ss >> col >> v1 >> op >> v2 >> eq >> var;
std::cout << v1 << " " << v2 << " " << var << std::endl;
return 0;
}
一个可能的解决方案是使用boost::split()
函数,它允许指定多个分隔符,并且不需要预先知道输入的大小:
#include <iostream>
#include <vector>
#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/split.hpp>
int main()
{
std::vector<std::string> tokens;
std::string s(":48754+7812=Abcs");
boost::split(tokens, s, boost::is_any_of(":+="));
// "48754" == tokens[0]
// "7812" == tokens[1]
// "Abcs" == tokens[2]
return 0;
}
或者,使用sscanf()
函数:
#include <iostream>
#include <cstdio>
int main()
{
const char* s = ":48754+7812=Abcs";
int X, Y;
char Z[100];
if (3 == std::sscanf(s, ":%d+%d=%99s", &X, &Y, Z))
{
std::cout << "X=" << X << "\n";
std::cout << "Y=" << Y << "\n";
std::cout << "Z=" << Z << "\n";
}
return 0;
}
然而,这里的限制是在解析输入之前必须决定字符串(Z
)的最大长度。
scanf
。虽然它不是过度C++风格的,但只需极少的代码即可完成任务。char a[101], b[111], c[121];
sscanf(":48754+7812=Abcs", ":%100[^+]+%110[^=]=%120s", a, b, c);
string sa(a), sb(b), sc(c);
cout << sa << "-" << sb << "-" << sc << endl;
这个想法是使用非常有限的正则表达式语法来指定读取的字符串所接受的字符。在这种情况下,第一个字符串被读取到加号,第二个字符串被读取到等号。
#include <boost/regex.hpp>
#include <iostream>
int main()
{
boost::regex re("\":(\\d+)\\+(\\d+)=(.+)\"");
std::string example = "\":48754+7812=Abcs\"";
boost::smatch match;
if (boost::regex_match(example, match, re))
{
std::cout << "f number: " << match[1] << " s number: " << match[2] << " string: " << match[3]
<< std::endl;
}
else
{
std::cout << "not match" << std::endl;
}
}
第二种方式仅适用于字符串。
#include <string>
#include <iostream>
int main()
{
std::string s = "\":48754+7812=Abcs\"";
std::string::size_type idx = s.find(":");
std::string::size_type end_first = s.find("+", idx + 1);
std::string f_number = s.substr(idx + 1, end_first - (idx + 1));
std::cout << f_number << std::endl;
std::string::size_type end_second = s.find("=", end_first + 1);
std::string s_number = s.substr(end_first + 1, end_second - (end_first + 1));
std::cout << s_number << std::endl;
std::string::size_type string_end = s.find("\"", end_second);
std::string str = s.substr(end_second + 1, string_end - (end_second + 1));
std::cout << str << std::endl;
}
[\d]
的标准方法是[[:digit:]]
。无论如何,最后一句话,如果您使用Clang,对C ++ 11正则表达式的支持会更好。通过正确的语法调整,您的示例代码就可以在那里工作了。 - jogojapan