您的位置:首页 > 编程语言 > C语言/C++

[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-stdstring

basic_string

can-i-convert-a-reverse-iterator-to-a-forward-iterator

std::reverse_iterator::base

使用ctype里的isxxx函数时要注意的事项
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: