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

标签: trim移除前后空格stringC++
1621人阅读 评论(0) 收藏 举报
分类:

场景

  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函数时要注意的事项

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:771571次
    • 积分:9889
    • 等级:
    • 排名:第1743名
    • 原创:266篇
    • 转载:17篇
    • 译文:2篇
    • 评论:140条
    同行
    任务
    1. 阅读 《加密与解密》并总结 (2017年).
    QQ: 632994155
    博客专栏
    最新评论