一、简介

      Linux下对字符串的操作使用频率高,在此总结部分功能。其中包括字符串的特征字符的分割、字符串左右边缘空格的去除(也可去掉左右特征字符串)及字符串大小转换。

二、详解

1、字符串分隔

(1)strtok.cpp:

#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
//字符分隔
void string_to_array(const string& source, char delimiter, vector<string>& the_vector)
{
    string dest = "";
    int i;
    the_vector.resize(0);
    for (i = 0; i < source.length(); i++) {
        if (source[i] != delimiter)  dest += source[i];
        else {
            if (dest.empty() == false) {   //不为空
                the_vector.push_back(dest);
                dest = "";
            }
        }
    }
    if (dest.empty() == false) the_vector.push_back(dest);
}
void chars_to_vector(char *str, char *delimiter, vector<string> &result)
{
    int i;
    string dest = "";
    for(i = 0; i < strlen(str); i++) {
        if (memcmp(&str[i], delimiter , strlen(delimiter)) == 0) {  //找到
            result.push_back(dest);
            i = i + 1;     //skip delimiter, i++ will skip one
            dest = "";
        }
        else {
            dest += str[i];
        }
    }
    if (dest != "")  result.push_back(dest);
}
void chars_to_list(const char *str, const char split, list<string>& lstr)
{
    char buff[1024] = {0};
    char tmp[100] = {0};
    char *pch = NULL;
    bool bFound = false;
    strcpy(buff, str);
    while(1) {
        pch = strchr(buff, split);
        if (pch == NULL) {
            break;
        }
        bFound = true;
        memset(tmp, 0, sizeof(tmp));
        strncpy(tmp, buff, pch - buff);
        tmp[pch - buff] = '\0';
        lstr.push_back(tmp);
        strcpy(buff, pch + 1);
    }
    if ( ( bFound == true) || (strlen(buff) > 0) ) {
        lstr.push_back(buff);
    }
}

void chars_to_chars(char *str, char delm, char array[][20])
{
    char *p = str;
    char *q = NULL;
    int num;
    int count = 0;
    while(1) {
        if (p[0] == '\0')  break;
        else {
            q = p;
            num = 0;
            while ((q[0] != delm) &&(q[0] != '\0')) {
                num ++;
                q ++;
            }
            strncpy(array[count], p, num);
            count++;
            p = q;
            p ++;
        }
    }
}
/***使用strtok_r多个分隔符,.|分隔****/
void chars_to_strtok(char *stok_char, const char *stok_delm, vector<string> &v_result)
{
    char *str = (char *)malloc(strlen(stok_char) + 1);
    memset(str, 0, strlen(stok_char) + 1);
    strcpy(str, stok_char);
    char *result = NULL;
    char *p_tmp = NULL;

    result = strtok_r(str, stok_delm, &p_tmp);
    while(result != NULL) {
        v_result.push_back(result);
        result = strtok_r(NULL, stok_delm, &p_tmp);
    }
}
int main()
{
    /************单个字符分隔**************/
    string str = "ac d, ddd,ccc";
    char delimiter = ',';
    vector<string> final;
    string_to_array(str, delimiter, final);
    for(int i = 0; i < final.size(); i++) {
        cout<<final[i]<<endl;
    }
    /************多个字符分隔**************/
    char source[] = "name e|.num|.money";
    char delm[] = "|.";
    vector<string> out;
    chars_to_vector(source, delm, out);
    for(int i = 0; i < out.size(); i++) {
        cout<<out[i]<<endl;
    }
    /***********单个字符分隔另一种方式************/
    cout<<"***************chars to list***************"<<endl;
    char list_str[] = "ac d, ddd,ccc";
    char list_sep = ',';
    list<string> lstr;
    chars_to_list(list_str, list_sep, lstr);
    list<string>::iterator it;
    for ( it=lstr.begin(); it != lstr.end(); it++ ) {
        cout<<*it<<endl;
    }
    cout<<"****************************"<<endl;
    char to_char[] = "ao,yang,de,di,pan";
    char to_delm = ',';
    char to_array[10][20] = {0};
    chars_to_chars(to_char, to_delm, to_array);
    for(int i = 0; i < 10, strlen(to_array[i]) > 0; i++)  cout<<to_array[i]<<endl;
    cout<<"****************************"<<endl;
    char stok_char[] = "ao,yang.de,di|pan";
    char stok_delm[] = ",.|";
    vector<string>v_result;
    chars_to_strtok(stok_char, stok_delm, v_result);
    for(int i = 0; i < v_result.size(); i++)  cout<<v_result[i]<<endl;
    return 0;
}

(2)编译运行

g++ -o scanfile scanfile.cpp 
./scanfile

2、字符串去特征字符(空格等)

(1)trim.cpp:
#include <iostream>
#include <algorithm>
#include <string>
#include <string.h>
using namespace std;
/***去掉string中单个字符***/
void string_trim(string &str, const char ch)
{
    string::iterator it;
    for (it = str.begin(); it < str.end(); it++) {
        if (*it == ch) {
            str.erase(it);
            it--;
        }
    }
}
/***去掉字符的左边的空格或其他字符***/
void ltrim(char *str, const char ch)
{
    char *ptr;
    for (ptr = str; *ptr; ptr++) {
        if(*ptr != ch)  break;
    }
    strcpy(str, ptr);
}
/***去掉字符的右边的空格或其他字符***/
void rtrim(char *the_str, const char ch)
{
    int i;
    int len = strlen(the_str);
    for (i = len - 1; i >= 0; i--) {
        if (the_str[i] != ch)  break;
    }
    the_str[i + 1] = '\0';
}
/***去掉字符左边顺序的多个字符***/
void ltrim(char* the_str, const char* fill)
{
    char *ptr = the_str;
    while (strncmp(ptr, fill, strlen(fill)) == 0) {  //相等
        ptr += strlen(fill);
    }
    if (ptr != the_str)  strcpy(the_str, ptr);
}
/***去掉字符右边顺序的多个字符***/
void rtrim(char* the_str, const char* fill)
{
    char *p = the_str + strlen(the_str) - strlen(fill);
    cout<<"p="<<p<<endl;
    while(strncmp(p, fill, strlen(fill)) == 0 && p >= 0) { //匹配
        p = p - strlen(fill);
        cout<<p<<endl;
    }
    int len = p - the_str + strlen(fill);
    the_str[len] = '\0';
}
/***fill指包含多个不同字符,可以是不连续的***/
void ltrim_leap(char* the_str, const char* fill)
{
    char* ptr;
    for (ptr = the_str; *ptr; ptr++) {
        if(!strchr(fill, *ptr))  break;
    }
    strcpy(the_str, ptr);
}
/***fill指包含多个不同字符,可以是不连续的***/
void rtrim_leap(char* the_str, const char* fill)
{
    int i;
    int len = strlen(the_str);
    for (i = len - 1; i >= 0; i--) {
        if(!strchr(fill, the_str[i]))  break;
    }
    the_str[i + 1] = '\0';
}
/***综上可以构成略去左右空格函数***/
void trim(char* the_str, const char ch)
{
    rtrim(the_str, ch);
    ltrim(the_str, ch);
}
int main()
{
    cout<<"**************"<<endl;
    string str = "ao&yang";
    char ch = '&';
    string_trim(str, ch);
    cout<<str<<endl;

    char data[] = "   aoa yang !ao  ";
    char ch_d = ' ';
    ltrim(data, ch_d);
    rtrim(data, ch_d);
    cout<<"data:"<<data<<endl;
    ltrim(data, "ao");
    rtrim(data, "!ao");
    cout<<data<<endl;
    cout<<"**************"<<endl;
    return 0;
}
(2)编译运行:
g++ -o trim trim.cpp 
./trim

3、字符串大小写转换

(1)部分代码
#include <iostream>
#include <string>
#include <string.h>
#include <stdarg.h>
using namespace std;
void upper(char *str)
{
  for (char *ptr = str; *ptr != '\0'; ptr++) {
    *ptr = toupper(*ptr);
  }
}
void upper(string& the_str)
{
  for (int i  = 0 ; i < the_str.size(); i++ ) {
    the_str[i] = toupper( the_str[i] );
  }
}
void lower(char* the_str)
{
  for (char* ptr = the_str; *ptr; ptr++) {
    *ptr = tolower(*ptr);
  }
}
void lower(string& the_str)
{
  for (int i  = 0 ; i < the_str.size(); i ++ ) {
    the_str[i] = tolower( the_str[i] );
  }
}

4、字符串其他操作

(1)字符串替换
/***凡是在字符串中的字符全部替换掉***/
void replace(char* the_str,char *oldchs,char newch)
{
  for (char* ptr = the_str; *ptr; ptr++) {
    if (strchr(oldchs,*ptr)) {
      *ptr = newch;
    }
  }
}
(2)格式化变长参数
void writeLog(char* section, const char* format, ...)
{
  char t_format[81920];
  memset(t_format, 0, sizeof(t_format));
  va_list vl_fmt;      //参数列表
  va_start(vl_fmt, format);
  vsprintf(t_format, format, vl_fmt);    //格式化处理format到字符串buf_Format
  va_end(vl_fmt);
}
(3)变长参数处理
/***把变长参数格式化到字符串***/
//此函数未理解,以后运用时再加以熟悉
int super_sscanf(const char *buf,char sp,const char *fmt,...)  //sp分隔符
{
  va_list arglist;
  int   value_type;
  int   is_format;
  int   is_token;
  
  va_start(arglist,fmt);
  is_format = 0;
  is_token = 0;
  while(1)
  {
    if (*fmt == '%')
    {
      is_format ++;
    }
    else if (*fmt == 's' || *fmt == 'S')
    {
      value_type = 0;
      is_token ++;
    }
    else if (*fmt == 'd' || *fmt == 'd' || *fmt == 'i' || *fmt == 'i')
    {
      is_token ++;
      value_type = 1;
    }
    else if (*fmt == 'c' || *fmt == 'C')
    {
      value_type = 2;
      is_token ++;
    }
    else if (*fmt == sp || *fmt == 0)
    {
      if ( is_format != 1 || is_token != 1)
      {
        return -1;
      }
      if (value_type == 0)
      {
        char *pstr = va_arg(arglist,char*);
        cout<<"buf1:"<<buf<<endl;
        cout<<"pstr1:"<<pstr<<endl;
        while(*buf != sp && *buf != 0)
        {
          if (*buf == '\n'||*buf == '\r')
          {
            buf ++;
            continue;
          }
          cout<<"buf2:"<<buf<<endl;
          cout<<"pstr2:"<<pstr<<endl;
          *pstr = *buf;
          buf ++;
          pstr ++;
        }
        buf ++;
        *pstr = 0;
        if (*fmt == 0)
          break;
        is_format = is_token = 0;
      }
      else if (value_type == 1)
      {
        int *num = va_arg(arglist,int*);
        *num = 0;
        while(*buf != sp && *buf != 0)
        {
          if (*buf < '0' || *buf > '9')
          {
            buf ++;
            continue;
          }
          *num = *num * 10 + *buf - '0';
          buf ++;
        }
        buf ++;
        is_format = is_token = 0;
      }
      else if (value_type == 2)
      {
        char *pch = va_arg(arglist,char*);
        *pch = 0;
        if (*buf != 0)
        {
          *pch = *buf;
        }
        while(*buf != sp && *buf != 0) buf ++;
        buf ++;
      }
      is_format = is_token = 0;
      if (*fmt == 0)
        break;
    }
    else if (*fmt == 0x20)
    {
      fmt ++;
      continue;
    }
    fmt ++;
  }
  return 0;
}

三、总结

(1)文中大部分是测试代码,若需要使用可直接从文中复制测试。
(2)字符串的操作还有很多思想比较特别的,总结后可以慢慢体会。
(3)若有建议,请留言,在此先感谢!

Logo

更多推荐