如何在C++中解析一个特殊的括号字符串
How to parse a special parenthetical string in C++
我有以下line
字符串:
(1,2,3);(3,4,5);(6,7,8);(9,10,11);
我想从第一个元组中提取数字1、2和3;从第二个开始依次为3、4和5,依此类推
到目前为止,我所做的是用这段代码提取由";"分隔的字符串:
stringstream ss(line);
string tuple;
vector<string> tuples_vec;
while (getline(ss, tuple, ';'))
tuples_vec.push_back(tuple);
好的,所以我想我会在tuples_vec
中有以下内容:
(1,2,3)
(3,4,5)
(6,7,8)
(9,10,11)
现在,我如何从中提取数字?请注意,可能存在数量可变的空格。
我认为这部分的一个想法可能是删除字符,直到第一个"(",并向后直到第一个")"。然后,用"1,2,3",我想我可以做一个while(getline(ss, number, ','))
,但我认为有一个更简单的方法。此外,我不知道如何编码这部分(删除字符)。
谢谢,
由于您没有声明检查输入语法有效性的要求,因此最简单的方法是
- 将每个"(",")"answers","替换为空格
- 替换每个";"使用换行符(这不是绝对必要的,但很简单)
- 使用例如
std::getline
一次读取一行,将其放在istringstream
中,然后一次从流中读取一个数字
我的想法是,通过代码接受简单的数字行,你可以通过打字或类似的方式来尝试。并且还支持其他格式。
祝你好运。
PS:这是而不是正则表达式的作业。;-)
首先,让我们从Line
类开始:
class Line
{
int a, b, c;
};
我们需要重载提取器,以便可以解析格式化的字符串:
template<class charT>
friend basic_istream<charT>& operator>>(basic_istream<charT>& is, Line& line)
{
return is >> line.a >> line.b >> line.c;
}
但为了使提取工作,流需要"忽略"重要数据周围的字符。我们需要使流将'('
、','
、')'
和';'
解析为空白字符。
流对类型为char
的对象使用表查找。我们也可以自己制作桌子:
class line_parser : public std::ctype<char>
{
public:
static mask* make_table()
{
static std::vector<mask> v(classic_table(),
classic_table() + table_size);
int table[10] = {0x20, 0x0c, 0x0a, 0x0d, 0x09,
0x0b, '(', ',', ')', ';'};
// ^^^^^^^^^^^^^^^^^^
for (int i : table)
v[i] |= space;
return &v[0];
}
explicit line_parser(int refs = 0) : ctype(make_table(), false, refs) { }
};
这是一个派生类方面。我们可以将这一方面融入流中,如下所示:
stringstream ss(line);
ss.imbue(locale(ss.getloc(), new line_parser));
但说实话,这有点乏味。用户不仅必须在流中注入一个新的区域设置,而且如果以后想使用以前的格式设置,他们还必须重新构建原始区域设置。为了方便这一点,我们必须找到一些封装此功能的方法。我们将创建一个为我们做这件事的操纵器:
template<class Line>
class line_extractor
{
public:
line_extractor(Line& other)
: line(other)
{ }
private:
Line& line;
template<class charT>
void do_input(basic_istream<charT>& is) const
{
// imbue the new locale
locale loc = is.imbue(locale(is.getloc(), new line_parser));
is >> line;
is.imbue(loc); // imbue the original locale
}
template<class charT>
friend basic_istream<charT>& operator>>(basic_istream<charT>& is,
const line_extractor& le)
{
le.do_input(is);
return is;
}
};
然后为了减少代码,从一个函数返回:
template<class Line>
line_extractor<Line> get_line(Line& l)
{
return line_extractor<Line>(l);
}
现在我们完成了。输入可以简单地完成:
stringstream ss(line);
vector<Line> v;
for (Line line; ss >> get_line(line); )
{
v.push_back(line);
}
您还应该添加用于检索a
、b
和c
的值的方法。
这是一个演示
std::string str; // input data
std::stringstream ss;
int x, y, z;
char fake;
ss << str;
ss >> fake >> x >> fake >> y >> fake >> z >> fake;
x, y, z; // output data
- 为什么 sscanf 无法从一个字符串中读取uint64_t和字符?
- 如何检查一个c++字符串中有多少相同的字符/数字
- 获取用C/C++打印的最后一个字符串
- cin >> int 给定一个字符串将 int 赋值为 0
- 我如何通过引用将 c++ 字符串分配给另一个字符串
- 使用另一个字符串从字符串中删除空格
- 有没有办法使用 strcpy 将字符串数组复制到另一个字符串或其他数组中?
- 当分配一个字符串值并稍后通过分配另一个值进行更改时C++如何管理内存?
- 我已经建立了递归关系,它找到了两个字符串之间最长的连续公共字符串,我怎么能跳过其中一个字符串中的一个字符
- C++为 void 指针分配一个字符串
- 如何在使用 getch 后在另一个字符串的末尾连接一个字符串
- 给定一个单词数组和一个字符串,如何计算给定字符串中的所有单词
- 如何在另一个字符串的x位置插入一个字符串?
- 有没有办法我可以在 C++ 中使用 if 语句来说明如果一个字符串不是两个名称的 eqal,它会给出一个输出,ATM i
- 在另一个字符串中插入文件扩展名之前的字符串
- 我有一个返回字符串向量的函数.它需要两个字符串,并且返回一个字符串中缺少的字符串
- C++自定义流操纵器,用于更改流上的下一个字符串
- 从类返回一个字符串 — 奇怪的行为
- 从我的2d数组中的一列返回的字符串值被压缩为一个字符串(在Mac os上打开Windows txt文件)
- 你能从"volatile const char*"构造一个字符串吗?(不使用`const_cast`