在 C++ 中在左侧拆分字符串
Posted
技术标签:
【中文标题】在 C++ 中在左侧拆分字符串【英文标题】:Split string on the left in C++ 【发布时间】:2015-08-08 20:55:44 【问题描述】:我正在尝试编写一个简短而愚蠢的方程解析器,并且需要围绕给定的运算符拆分一个字符串。我可以通过
拆分字符串的右侧return std::string(oprtr + 1, equ.end());
其中 equ 是字符串,而 oprtr 是我需要从中拆分的位置的迭代器。这样做很完美,但是从左边分开却不行:
return std::string(equ.begin(), oprtr - 1);
====
terminate called after throwing an instance of 'std::length_error'
what(): basic_string::_S_create
我尝试了很多其他我并不引以为豪的讨厌的变通方法,比如
return equ.substr(0, std::distance(equ.begin(), oprtr));
这不会给出错误,但实际上只是返回整个方程。我在这里做错了什么?
【问题讨论】:
没有足够的代码来解决这个问题。什么是操作? optrr 是一个迭代器,指向我需要从中拆分的位置。抱歉,我会将其添加到问题文本中。return std::string(equ.begin(), oprtr);
和 return std::string(oprtr + 1, equ.end());
在我看来是正确的。不知道为什么要从结束位置减去一个。
需要从结束位置减去一个,因为我不希望包含运算符本身。在任何情况下,return std::string(equ.begin(), oprtr);
是我想使用的主要,但仍然抛出上述错误。
@Sourec 您无需减去一个即可不包含运算符。我认为需要阅读迭代器范围。 string(i, j) 创建一个从 i 开始直到 但不包括 j的字符串。
【参考方案1】:
g++ 4.8.2
为我工作:
#include <string>
#include <algorithm>
#include <iostream>
int main()
std::string eq("a+b=c");
std::string::iterator opit = std::find(eq.begin(),eq.end(),'=');
std::string lhs = std::string(eq.begin(),opit);
std::cout << "lhs: " << lhs << "\n";
return 0;
输出是:
lhs: a+b
【讨论】:
所以这也适用于我,但它使用与我之前尝试过的完全相同的东西,使用构造函数进行拼接......但不知何故,这在没有引发错误的情况下工作。我必须假设它与 std::find() 有关,但不幸的是,这不适用于我的情况,整个事情实际上是在一个函数中,迭代器和字符串作为参数传入。 这就是线索,您正在传递迭代和迭代器指向的字符串的副本。您需要原始字符串,而不是副本。通过引用传递。 @Sourec 您真的应该发布一个演示错误的最小工作示例。好吧,约翰的暗示是真的。如果您通过std::string
,您将获得一份副本,但迭代器用于原始字符串。您应该传递参数类型为 std::string&
的原始字符串。【参考方案2】:
好像你在做这样的事情
void my_func(string equ, string::iterator oprtr)
string left = std::string(equ.begin(), oprtr);
string::iterator oprtr = equ.find('=');
my_func(equ, oprtr);
这行不通,因为在my_func
中,您有两个指向不同字符串的迭代器。因为调用my_func
时会复制原始字符串。
一种解决方法是通过引用传递
void my_func(string& equ, string::iterator oprtr)
另一个解决方法是使用整数而不是迭代器。整数不像迭代器那样绑定到一个特定的字符串实例。
【讨论】:
做到了,谢谢。我不知道我是怎么错过的,我想它只是没有引起我的注意,因为使用相同的技术向右拆分效果很好。非常感谢!以上是关于在 C++ 中在左侧拆分字符串的主要内容,如果未能解决你的问题,请参考以下文章