从 C++ 字符串中删除最后一个字符

Posted

技术标签:

【中文标题】从 C++ 字符串中删除最后一个字符【英文标题】:Remove last character from C++ string 【发布时间】:2011-01-19 15:16:37 【问题描述】:

如何?

我试过st = substr(st.length()-1);,但没用。

【问题讨论】:

你想要一个删除了最后一个字符的新字符串还是没有最后一个字符的相同字符串? 对于 MFC Visual C++ CString:CString str=CString("Hello world"); str.Delete(str.GetLength()-1); 【参考方案1】:

如果您使用的是 C++11,则解决方案很简单。也可能是 O(1) 次:

st.pop_back();

【讨论】:

仅供参考 - 它仅受 GCC 4.7 支持(当然,带有 -std=c++11 编译开关) 别忘了查看length() 是的,它出现在页面下方太远了..! 最好添加最方便的方法来删除最后一个 X 字符。 The behavior is undefined if the string is empty. 来自here【参考方案2】:

对于非变异版本:

st = myString.substr(0, myString.size()-1);

【讨论】:

@MatthieuM。您的示例令人困惑,我认为问题的本质是修改原始字符串,在您的示例中,您没有修改原始字符串,因为在您的示例中,原始字符串被称为“myString”,这会造成混淆,在问题中它是“st”。您的代码应为:st = st.substr(0, st.size()-1)。但它仍然看起来不正确,我认为正确的方法是使用用于此任务的函数,它称为erase(),代码为:st.erase(st.size()-1)。这将被称为“变异版本”。 @CzarekTomczak:我知道这不是所要求的,因此在实际要点之前的免责声明。 @MattPhillips:他的解决方案是特定于 C++11 的(pop_back 在 C++03 中不存在),它也是一个就地修改(并且 OP 从未澄清他是否是否想要就地)...因此,他有一个正确答案,但不是唯一可能的答案。【参考方案3】:
if (str.size () > 0)  str.resize (str.size () - 1);

std::erase 替代方案很好,但我喜欢“- 1”(无论是基于大小还是结束迭代器)——对我来说,它有助于表达意图。

顺便说一句 - 真的没有 std::string::pop_back 吗? - 看起来很奇怪。

【讨论】:

C++03中没有std::string::pop_back;不过,它是在 C++0x 中添加的。 好的 - 谢谢。它引起了一些混乱——我可以发誓我用过它,但它不存在。也许我在某个编译器的某个地方有一个非标准库(在 VC++2003、VC++2008、MinGW GCC3 MinGW GCC 4 和 Linux GCC 4 之间,你确实有一些差异)。更有可能的是,我只是对其他类型感到困惑。 resize() 可能不适合这种用途,它是一个与内存相关的函数,erase() 用于删除字符。 @Czarek Tomczak - 很抱歉回复晚了,但resize 是一个调整大小的函数,不再是一个内存函数,任何其他可能增加所需内存的东西。例如,如果您将resize 设置为更小的尺寸,它不会 减少保留的内存。我认为您正在考虑reserve,如果要求,它至少可能减少分配的内存 - 请参阅resize here和reserve here。 如果 (!str.empty()) 优先于大小【参考方案4】:
buf.erase(buf.size() - 1);

这假设您知道字符串不为空。如果是这样,您将收到 out_of_range 异常。

【讨论】:

buf[buf.size()-1] = '\0';不会删除任何东西 - 它只是将那里的字符更改为零值。 std:;strings 可以愉快地包含这样的字符。 尼尔是正确的。我可能应该在我的回答中澄清这一点。第二个选项将有效地更改最后一个字符的值,因此它不会打印,但字符串长度将保持不变。使用擦除实际上“删除”了最后一个字符,并会改变字符串的大小。 @RC 它将打印,假设您使用类似 cout size() 而不是另一个答案的end() 有什么更好的地方?【参考方案5】:

str.erase( str.end()-1 )

参考:std::string::erase() prototype 2

不需要 c++11 或 c++0x。

【讨论】:

这可能会导致奇怪的情况:字符串的大小已减小但最后一个字符未设置为'\0'。 @Deqing 你能详细说明一下这种情况会发生什么吗? 轻松修复:只需str[str.length()-1] = 0; str.erase(str.end()-1); @Dequing:您的示例无效。擦除减小了字符串的大小,所以对s[2]的访问是非法的。 EML 是正确的。这就是为什么在您要逐个字符访问并期望 \0 终端时使用 c_str() 很重要的原因。否则访问 std:string 的唯一正确方法是使用迭代器。【参考方案6】:

这就是你所需要的:

#include <string>  //string::pop_back & string::empty

if (!st.empty())
    st.pop_back();

【讨论】:

【参考方案7】:
int main () 

  string str1="123";
  string str2 = str1.substr (0,str1.length()-1);

  cout<<str2; // output: 12

  return 0;

【讨论】:

【参考方案8】:

使用 C++11,您甚至不需要长度/大小。只要字符串不为空,就可以进行如下操作:

if (!st.empty())
  st.erase(std::prev(st.end())); // Erase element referred to by iterator one
                                 // before the end

【讨论】:

【参考方案9】:

str.erase(str.begin() + str.size() - 1)

很遗憾,str.erase(str.rbegin()) 无法编译,因为 reverse_iterator 无法转换为 normal_iterator。

C++11 在这种情况下是你的朋友。

【讨论】:

这个方法也有问题,最后一个字符没有设置为'\0'。 不做str.erase(str.end() - 1)的任何特殊原因?【参考方案10】:
#include<iostream>
using namespace std;
int main()
  string s = "Hello";// Here string length is 5 initially
  s[s.length()-1] = '\0'; //  marking the last char to be null character
  s = &s[0]; // using ampersand infront of the string with index will render a string from the index until null character discovered
  cout<<"the new length of the string "<<s + " is " <<s.length();
  return 0;

【讨论】:

【参考方案11】:

如果长度不为零,也可以

str[str.length() - 1] = '\0';

【讨论】:

将最后一个字符设置为\0 不会更改字符串的长度。 str.length() 将不准确。 是的,我现在看到了。我们正在考虑 C++。你是对的,它不会改变字符串的长度

以上是关于从 C++ 字符串中删除最后一个字符的主要内容,如果未能解决你的问题,请参考以下文章

C ++从多行字符串中删除新行

从字符串中删除最后一个字符

我们可以同时从 C++ 字符串中删除两个子字符串吗?

从字符串中删除最后一个字符。斯威夫特语言

如何从字符串中删除最后一个字符

从字符串中的多个数字中删除前导零? [C++]