从字符串中修剪/删除制表符 ( "\t" )
Posted
技术标签:
【中文标题】从字符串中修剪/删除制表符 ( "\\t" )【英文标题】:Trim / remove a tab ( "\t" ) from a string从字符串中修剪/删除制表符 ( "\t" ) 【发布时间】:2009-02-17 10:47:35 【问题描述】:谁能建议一种从字符串中去除制表符 ("\t"s) 的方法? CString 或 std::string。
例如“1E10 ”变成“1E10”。
【问题讨论】:
你的意思是从头开始还是从头开始?或者从字符串中的任何地方? “abc\tdef”应该保持原样,还是简化为“abcdef”? 我应该更清楚一点,我的意思是从字符串中的任何地方。 【参考方案1】:hackingwords' answer 让你成功了一半。但是来自<algorithm>
的std::remove()
实际上并没有使字符串更短——它只是返回一个迭代器,说“新序列将在此处结束”。您需要致电 my_string().erase()
来执行此操作:
#include <string>
#include <algorithm> // For std::remove()
my_str.erase(std::remove(my_str.begin(), my_str.end(), '\t'), my_str.end());
【讨论】:
std::remove() 链接已损坏。正确链接:en.cppreference.com/w/cpp/algorithm/remove @SebiSebi:谢谢你,修复!【参考方案2】:如果你想删除字符串中的所有出现,那么你可以使用erase/remove idiom:
#include <algorithm>
s.erase(std::remove(s.begin(), s.end(), '\t'), s.end());
如果您只想删除字符串开头和结尾的制表符,可以使用boost string algorithms:
#include <boost/algorithm/string.hpp>
boost::trim(s); // removes all leading and trailing white spaces
boost::trim_if(s, boost::is_any_of("\t")); // removes only tabs
如果使用 Boost 开销太大,您可以使用 find_first_not_of
和 find_last_not_of
字符串方法滚动自己的修剪函数。
std::string::size_type begin = s.find_first_not_of("\t");
std::string::size_type end = s.find_last_not_of("\t");
std::string trimmed = s.substr(begin, end-begin + 1);
【讨论】:
std::remove() 不会使字符串更短——它只是返回一个迭代器,说“新字符串到此结束”。之后您需要使用该迭代器调用 s.erase() 以实际缩短字符串。 你说得对,我忘了使用擦除/删除成语。已更正。【参考方案3】:remove
算法将所有不被删除的字符移到开头,覆盖已删除的字符,但它不会修改容器的长度(因为它适用于迭代器并且不知道底层容器)。为此,请致电erase
:
str.erase(remove(str.begin(), str.end(), '\t'), str.end());
【讨论】:
我认为您将erase() 的参数弄混了。您想从 remove() 返回的迭代器中删除 到 str. 的 end P.S:实际上我不认为 remove() 将找到的字符移到末尾 - 我认为末尾只会包含它最初包含的任何内容。 @j_r_h:不,确实如此。基本上,remove(a, b, v)
完全等于 stable_partition(a, b, p)
谓词 p = _1 != value
。
你确定吗?根据sgi.com/tech/stl/remove.html:“[new_last, last) 范围内的迭代器仍然是可取消引用的,但它们指向的元素是未指定的。当然是 MinGW 和 MSVC++8 的 remove() != stable_partition() 实现。
(续)也就是说,我现在明白你是对的,它们并不相同; remove
只是将其他元素移到前面,它不会将已删除的元素移到后面。所以,是的,你一直都是对的。但我必须先对其进行测试:pastie.org/396239 所以,感谢您的坚持!【参考方案4】:
由于其他人已经回答了如何使用 std::string 执行此操作,因此您可以将以下内容用于 CString:
myString.TrimRight( '\t' ); // trims tabs from end of string
myString.Trim( '\t' ); // trims tabs from beginning and end of string
如果你想去掉所有的制表符,即使是字符串内的制表符,使用
myString.Replace( _T("\t"), _T("") );
【讨论】:
在字符串上使用 TrimRight 和 Trim 方法需要包含哪个标头/库?我已经完成了#include扫描字符串并删除所有找到的出现。
【讨论】:
【参考方案6】:HackingWords 即将到来:将擦除与删除结合使用。
std::string my_string = "this\tis\ta\ttabbed\tstring";
my_string.erase( std::remove( my_string.begin(), my_string.end(), '\t'), my_string.end());
【讨论】:
我认为你犯了和 Konrad Rudolph 一样的错误——你需要从 std::remove() 返回的迭代器中删除 到 end i> 的字符串。【参考方案7】:CString 替换?
替换('\t', '')
【讨论】:
行不通。 '' 代表 NULL 字符(至少在 VC++ 中)。会引起问题。 更具体地替换("\t", "") 我没有测试 is 但我想使用 '\t' 因为我认为 "\t" 会查找文本 \t 而不是制表符(不确定) . 不,replace("\t", "") 将根据需要工作,但它不是很省时。转义序列在字符文字和字符串文字中的工作方式相同。【参考方案8】:第一个想法是使用remove
remove(myString.begin(), myString.end(), "\t");
如果比较不起作用,您可能不得不使用 remove_if。
【讨论】:
remove() 是其中的一半——您还需要使用对 myString.erase() 的调用来包装对 remove() 的调用,因为 remove() 实际上并没有缩短字符串 (它不(也不能)知道如何)。【参考方案9】:我想知道为什么没有人这样修剪字符串:
void trim (string& s)
string t = "";
int i = 0;
while(s[i] == ' ') i++;
while(s[i] == '\t') i++;
for(i; i < s.length(); i++)
t += s[i];
s = t;
【讨论】:
因为它不能正确处理所有情况。它只会跳过前导空格,然后是前导制表符,并且仅按此顺序。以上是关于从字符串中修剪/删除制表符 ( "\t" )的主要内容,如果未能解决你的问题,请参考以下文章