使C ++ std :: string以指定字符结尾?

时间:2017-03-01 20:16:47

标签: c++ string c++11 c++14

假设我正在遍历一串长度为n的字符串。我希望它以符合某些条件的特定角色结束。我知道 C样式字符串可以通过在位置处分配字符'\ 0'来终止 i 位置我在字符数组中。

有没有办法在 std :: string (C ++样式字符串)中实现相同的结果?我可以想到substr,erase等等,但它们的复杂性都是线性的,我无法承受。

TL; DR,是否有std :: string的“结束”字符?我可以以某种方式使结束迭代器指向当前字符吗?

5 个答案:

答案 0 :(得分:5)

您可以使用resize

std::string s = /* ... */;

if (auto n = s.find(c); n != s.npos) {
  s.resize(n);
}

答案 1 :(得分:3)

这里的逻辑答案是basic_string::resize标准关于此功能的说法是:

  

效果:改变*this指定的字符串的长度,如下所示:

     
      
  • 如果n <= size(),该函数将*this指定的字符串替换为长度为n的字符串,其元素是{{1}指定的原始字符串的初始元素的副本}}。
  •   
  • 如果*this,该函数将n > size()指定的字符串替换为长度为*this的字符串,其第一个n元素是由{指定的原始字符串的副本{1}},其余元素全部初始化为size()
  •   

现在,这看起来非常像线性时间。但是,该标准没有明确规定事情会以这种方式发生。他们只说这将“好像”以这种方式发生。因此,通过移动一个指针并写入NUL字符,实现完全可以自由地实现缩小版*this。标准中的任何内容都不会禁止此类实施。

所以真正的问题是......是完整的笨蛋写的标准库实现吗?它们肯定是可能的。但是这样做可能是明智的。

就个人而言,我只是假设图书馆实施者知道他们在做什么而使用c。毕竟,如果他们不能写出那么简单的优化,那么谁知道他们做错了什么呢?如果你不能相信你的标准库实现不做蠢事,那么你就不应该在性能关键代码中使用它。

答案 2 :(得分:2)

  

是否有std :: string的“end”字符?

没有。可以定义非空终止的std::string。您将无法为此类字符串执行一些操作,例如将std::string:data()的返回值视为空终止的C字符串 1 ,但std::string可以以这种方式构建。

  

我可以以某种方式使结束迭代器指向当前字符吗?

要获得某个角色的std::string::iterator点,您必须遍历该字符串。

E.g。

std::string str = "This is a string";
auto iter = str.begin();
auto end = iter;
while ( end != str.end() && *end != 'r' )
   ++end; 

之后,iterend定义的范围包含字符串"This is a st"

如果这是不可接受的,您必须调整代码以检查每个步骤的字符值。

std::string str = "This is a string";
auto iter = str.begin();

// Break when 'r' is encountered or end of string is reached.
while ( iter != str.end() && *iter != 'r' )
{
   // Use *iter
   ...
}

1 感谢@Cubbi指出我所说的错误。如果使用早于C ++ 11的C ++版本,std::string::data()可以返回非空终止的char const*。如果使用C ++ 11或更高版本,则需要std::string::data()才能返回空终止char const*

答案 3 :(得分:1)

std::string没有&#34;结束字符&#34;像c样式字符串。您可以在单个std::string中包含许多空终止符。如果您希望字符串在某个字符后结束,那么您需要erase字符串中最后一个字符后面的其余字符。

在你的情况下会给你类似的东西

string_variable.erase(pos_of_last_character + 1)

答案 4 :(得分:0)

  

TL; DR,是否有std :: string的“结束”字符?我可以以某种方式使结束迭代器指向当前字符吗?

不是真的。 std::string使用std::string::size()功能跟踪存储和维护的字符数,与'\0'等任何标记字符无关。

虽然从std::string初始化const char*时会考虑这些。