[C/C++]_[初级]_[Trim掉字符串的前后空格]
2016-05-30 10:09
393 查看
场景
C++ 字符串Trim空格一直不在标准库里, 但是又很常用, 比如在界面输入一些字符串需要过滤掉前后空格后保存到数据库里;又或者需要进行字符串比较时过滤掉前后空格来精确比较都需要用到Trim方法.Object-c的NSString有自己的一个方便的方法实现Trim行为.
text = [text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]
Java 的String也有自己的 trim()方法,确实 C++的字符串库我感觉可以模仿Java API 写成对应的标准库了.
import java.io.*; public class Test{ public static void main(String args[]){ String Str = new String(" Welcome to Tutorialspoint.com "); System.out.print("Return Value :" ); System.out.println(Str.trim() ); } }
之前写过一些Trim的C++函数,但是都不够精炼. 先参考 使用模板删除字符串前后空格((w)string space) 看以前写的实现是不是很冗余.再看现在的实现, 是否是发现很精简? 可惜的是使用模板必须是头文件. Trim后边的空格使用reverse_iterator, 很精巧.
template<class T> T& LTrim(T& t) { t.erase(t.begin(), std::find_if(t.begin(),t.end(),[](int i)->bool{return !isspace(i & 0xFF);})); return t; } template<class T> T& RTrim(T& t) { t.erase(std::find_if(t.rbegin(),t.rend(),[](int i)->bool{return !isspace(i & 0xFF);}).base(),t.end()); return t; } template<class T> T& Trim(T& t) { return RTrim(LTrim(t)); }
例子
顺便提醒下& 0xFF是为了过滤掉 > 255的字符, 比如wstring占用了两字节,在Windows下, > 255 的int 调用isspace会崩溃.std::reverse_iterator::base 的意思是返回一个当前 reverse_iterator 内部表示的 iterator,这样和erase的第2个参数.end()才能匹配. 而且用枚举对象不用担心下标越界问题.
#include "stdafx.h"
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <string>
#include <ctype.h>
using namespace std;
template<class T> T& LTrim(T& t) { t.erase(t.begin(), std::find_if(t.begin(),t.end(),[](int i)->bool{return !isspace(i & 0xFF);})); return t; } template<class T> T& RTrim(T& t) { t.erase(std::find_if(t.rbegin(),t.rend(),[](int i)->bool{return !isspace(i & 0xFF);}).base(),t.end()); return t; } template<class T> T& Trim(T& t) { return RTrim(LTrim(t)); }
void TestTrimString()
{
string wstr;
string wres;
wstr = "asdfasd 990";
Trim(wstr);
assert(wstr == "asdfasd 990");
wstr = "asdfasd 990 ";
Trim(wstr);
assert(wstr == "asdfasd 990");
wstr = " asdfasd 990";
Trim(wstr);
assert(wstr == "asdfasd 990");
wstr = " asdfasd 990 ";
Trim(wstr);
assert(wstr == "asdfasd 990");
wstr = "";
Trim(wstr);
assert(wstr == "");
wstr = " ";
Trim(wstr);
assert(wstr == "");
wstr = "\0";
Trim(wstr);
assert(wstr == "");
std::wstring w(L" hello ");
Trim(w);
assert(w == L"hello");
}
int main(int argc, char const *argv[])
{
TestTrimString();
system("pause");
return 0;
}
参考
whats-the-best-way-to-trim-stdstringbasic_string
can-i-convert-a-reverse-iterator-to-a-forward-iterator
std::reverse_iterator::base
使用ctype里的isxxx函数时要注意的事项
相关文章推荐
- 145. Binary Tree Postorder Traversal
- C语言求圆周率的简单实现方法
- C++的MFC 与 HTML 双向通讯
- leetcode #60 in cpp
- 【C语言】print 输出
- 在升序排序的数组中插入一个元素
- 寻找最高分成绩的学生
- C++界面库
- 飛飛(四十九)用友元函数来编写运算符重载
- (飛飛四十八)简单的运算符重载
- 结构体(Struct)联合体(Union)枚举(enum)总结
- 通用型线程池框架 C++
- 144. Binary Tree Preorder Traversal
- 94. Binary Tree Inorder Traversal
- leetcode #59 in cpp
- leetcode #58 in cpp
- leetcode #57 in cpp
- 一起talk C栗子吧(第一百五十九回:C语言实例--基于AF_INET域的数据报套接字通信)
- leetcode #56 in cpp
- leetcode #55 in cpp