C++ string字符串分割


一、find()配合substr()

    第一种办法是先通过find()函数查询到子字符串的位置,而后通过substr进行子字符串截取。
    关于find()函数共有以下几种:

    1.string中find()返回值是字母在母串中的位置(下标记录),如果没有找到,那么会返回一个特别的标记npos。(返回值可以看成是一个int型的数),示例如下:

#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
    find函数返回类型 size_type
    string s("1a2b3c4d5e6f7jkg8h9i1a2b3c4d5e6f7g8ha9i");
    string flag;
    string::size_type position;
    //find 函数 返回jk 在s 中的下标位置
    position = s.find("jk");
    if (position != s.npos)  //如果没找到,返回一个特别的标志c++中用npos表示,我这里npos取值是4294967295,
    {
        printf("position is : %d\n" ,position);
    }
    else
    {
        printf("Not found the flag\n");
    }
}
    2.返回子串出现在母串中的首次出现的位置,和最后一次出现的位置。示例如下:
flag = "c";
position = s.find_first_of(flag);
printf("s.find_first_of(flag) is :%d\n",position);
position = s.find_last_of(flag);
printf("s.find_last_of(flag) is :%d\n",position);
//s.find_first_of(flag) is :5
//s.find_last_of(flag) is : 25
    3.查找某一给定位置后的子串的位置,示例如下:
//从字符串s 下标5开始,查找字符串b ,返回b 在s 中的下标
position=s.find("b",5);
cout<<"s.find(b,5) is : "<<position<<endl;
//s.find(b,5) is : 23
    4.查找所有子串在母串中出现的位置,示例如下:
//查找s 中flag 出现的所有位置。
    flag="a";
    position=0;
    int i=1;
    while((position=s.find(flag,position))!=string::npos)
    {
        cout<<"position  "<<i<<" : "<<position<<endl;
        position++;
        i++;
    }
    //position  1 : 1
    //position  2 : 21
    //position  3 : 36
    5、反向查找子串在母串中出现的位置,通常我们可以这样来使用,当正向查找与反向查找得到的位置不相同说明子串不唯一。示例如下:
//反向查找,flag 在s 中最后出现的位置
flag="3";
position=s.rfind (flag);
printf("s.rfind (flag) :%d\n",position);

以上内容转载于https://www.cnblogs.com/wkfvawl/p/9429128.html,可获得更多示例。

    在获得子字符串位置后,则可通过substr()函数进行子字符串截取,对于string.subsrt(pos, n)函数,包含string中从pos开始的n个字符的拷贝(pos的默认值是0,n的默认值是string.size() - pos,即不加参数会默认拷贝整个s),若pos的值超过了string的大小,则substr函数会抛出一个out_of_range异常;若pos+n的值超过了string的大小,则substr会调整n的值,只拷贝到string的末尾,注意这里的n是所要截取的字符串长度,代码如下:

string FileName_Flag = "AVW_00_1_0_00.xml,1";
int posId = FileName_Flag.find(",");
scenarioName = FileName_Flag.substr(0, posId);
scenarioName = scenarioName.substr(0, scenarioName.length() - 4);
//scenarioName = "AVW_00_1_0_00"

    这样便可以不断地通过改变substr(pos,length)中的pos和length参数获得字符串中的子字符串。

二、使用strtok()函数

函数原型:char *strtok(char *s,const char *delim) 函数功能:分解字符串为一组字符串,s为要分解的字符串,delim为分隔字符串 描述:strtok()用来将字符串分割成一个个片段,参数s指向将要被分隔的字符串,参数delim则为分隔字符串,当strtok()在参数s的字符串中发现到参数delim的分隔字符时,则会将该字符改为'\0'字符,在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL.每次调用成功则返回被分隔片段的指针。 代码如下:
#include<string.h>
#include<stdio.h>

int main(){
	char s[] = "a,b*,c,d";
	const char *sep = ",*";	//可按多个字符来分割
	char *p;
	p = strok(s, sep);
	while(p){
		printf("%s ", p);
		p = strtok(NULL, sep);
	}
	printf("\n");
	return 0;
}
//输出: a b c d

关于C++ string的一些函数说明见:https://blog.csdn.net/modiziri/article/details/41748421

总结

    以上即为C++ string字符串分割的一些总结。
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
面试题,是纸上写的,发现了些错误,回来改进了下。写纸上和写计算机里并编译成功完全是两个效果。 开始没太多字符串操作,很繁琐、难点也多,后逐渐改进。 典型问题1: sizeof()局限于栈数组 char a[] = "asd213123123"; 形式,并且这种不能用'\0'判断是否结束(这种判断方式能很方便加在while条件中用于判断越界——b != '\0')。 如果是字符串常量: char *b = "dasadafasdf"; 这种情况,sizeof()就废掉了! 总之: 对号入座,前者sizeof、后者strlen~!不过sizeof(a)和strlen(b)还有另外一个区别,strlen不计算'\0',而sizeof要计算(前提是sizeof()不针对char指针) 典型问题2: 用什么来暂存并输出结果?还是只是记录下来相关位置——这是我底下未完成版本1想到的思路——用一个count[sizeof(A)]数组记录下A每个位置作为起点所能和B达到的最大重合,最后判断查找数组中最大值,此时目标子字符串的起点下标(i)和 i 对应的长度(counter[i])都有了。 这是针对不知道字符串大小并且不占用额外空间的做法,需要非常繁琐的操作,要加很多标记,越界判断也会有些麻烦(结合优势么,用字符串常量而不是栈空间中的字符数组,有'\0'——就好判断了!) (关于空间的占用,如果要用一个和字符串a一样长的数组counter来计录a中各起点对应与b最大重合子字符串,这个数组也要和a一样长,空间上也不合适,除非情形很特殊,a短b长,不然不如直接malloc()一个堆空间来储存当前最长“子字符串”,并实时更新) 先放一个改完编译测试成功的。 release1 //题目:要求比较A字符串(例如“abcdef"),B字符串(例如(bdcda)。找出重合度最大的子字符串,输出(根据OJ经验,输>出结果对即可) #include #include #include main(){ char *A = "abcderfghi"; char *B = "aderkkkkkabcd"; int i,j,c = 0,count = 0; unsigned int maxSeg = 0; int max = strlen(A) > strlen(B) ? strlen(A) : strlen(B); char* final = (char*)malloc(sizeof(char) * (max + 1)); final[max] = '\0'; for(i = 0;A[i] != '\0';i++){ for(j = 0;B[j] != '\0';j++){ while(A[i + c] == B[j] && A[i+c] != '\0' && B[j] != '\0'){ count++; c++; j++; }                         if(count > maxSeg){                                 strncpy(final,(A + i),count);                                 maxSeg = count;                         } count = 0; c = 0; } } printf("%s\n",final); free(final); } 这是能将就用的第一个版本~!关于结束符'\0'能否影响free()的使用,觉得是完全不用操心的,因为malloc的大小是系统来保存的,删除时候系统来接手就完了,而'\0'结束符只是针对一些常规字符串操作,比如printf()用%s控制输出时~! 新难点:找到的子字符串同时一样长怎么办?那我这只能叫做”第一个最长的重合字符串“用两块空间来存储?三
要将一个字符串分割并转换为一个列表,你可以使用不同的方法。其中一种方法是使用C#中的Array.ConvertAll方法。你可以使用Split方法将字符串分割成一个字符串数组,然后使用Array.ConvertAll方法将每个字符串转换为整数,并将结果存储在一个整数列表中。以下是一个示例代码: ```csharp string str = "1,2,3,4,5"; string\[\] strArray = str.Split(','); List<int> intList = Array.ConvertAll(strArray, int.Parse).ToList(); ``` 另一种方法是使用Guava库中的Splitter类。你可以使用on方法指定分隔符,trimResults方法去除每个分割后的字符串的空格,并使用splitToList方法将结果存储在一个字符串列表中。以下是一个示例代码: ```java String str = "a, b, c"; List<String> stringList = Splitter.on(",").trimResults().splitToList(str); ``` 还有一种方法是使用Apache Commons Lang库中的StringUtils类的join方法。你可以使用join方法将整数数组转换为一个字符串,可以选择指定分隔符。以下是一个示例代码: ```java int\[\] arr = {0, 1, 2, 3, 4, 5}; String str = StringUtils.join(arr, ","); ``` 希望这些方法能够帮助到你。 #### 引用[.reference_title] - *1* [C# string分割转int[] string分割转List<int>](https://blog.csdn.net/qq_27559331/article/details/80612972)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [字符串以逗号分隔的转换为List或数组方法](https://blog.csdn.net/m0_37914467/article/details/110821277)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值