linux下c/c++实例之八字符串分隔、去空格和转大小写
Linux下对字符串的操作使用频率高,在此总结部分功能。其中包括字符串的特征字符的分割、字符串左右边缘空格的去除(也可去掉左右特征字符串)及字符串大小转换。
·
一、简介
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)若有建议,请留言,在此先感谢!
更多推荐
已为社区贡献8条内容
所有评论(0)