心如止水

数学,算法,语言,界面,工具

[C/C++]_[初级]_[Trim掉字符串的前后空格]

场景

  1. C++ 字符串Trim空格一直不在标准库里, 但是又很常用, 比如在界面输入一些字符串需要过滤掉前后空格后保存到数据库里;又或者需要进行字符串比较时过滤掉前后空格来精确比较都需要用到Trim方法.

  2. Object-c的NSString有自己的一个方便的方法实现Trim行为.

text = [text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]
  1. 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() );
   }
}
  1. 之前写过一些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));
}

例子

  1. 顺便提醒下& 0xFF是为了过滤掉 > 255的字符, 比如wstring占用了两字节,在Windows下, > 255 的int 调用isspace会崩溃.
  2. 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函数时要注意的事项

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/infoworld/article/details/51535907
个人分类: 语言特性
所属专栏: C C++标准库
上一篇[C/C++11]_[初级]_[使用enumerations类型]
下一篇[C/C++]_[初级]_[使用remove,remove_if,remove_copy_if过滤元素或字符]
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭