Blackops

初心易得,始终难守

0%

字符串分割的几个方法

有时候会遇到类似于给你一行字符串,让你分割并获取出里面的几个子串的这种问题,这里个人总结了三个稍微好一点的方法

  1. 把string用istringstream类重定向
  2. 用scanf自带的转义字符匹配分割
  3. strtok处理含有特定分割标志的字符串

1.istringstream

相关头文件:<sstream>(不加这个头文件很可能会编译错误)

一种基于字符串的$I/O$方式,即从字符串(一般为$string$)中读取,而不是来自输入流,其分割是按空格分割。

假设给定一行包含很多个数字的字符串,每个数字用空格分割,最后求这一行的数字之和。

此时可以用一个$string$对象$str$储存这个字符串,然后用$str$初始化$istringstream$对象$strin$,然后就可以用$>>$操作符从$strin$中输入了。

PS.据说多次使用这个东西似乎会让占用很多内存,此时用$strin.str(“”)$可以释放内存并清空$strin$的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <sstream>
using namespace std;
int main(void)
{
string str;
while (getline(cin, str))
{
// cout << str << endl;
istringstream strin(str);
int sum = 0, num;
while (strin >> num)
{
sum += num;
}
cout << sum << endl;
}
return 0;
}

2.scanf

相关头文件:<stdio.h>

由于scanf的参数中可以用一些正则表达式,因此像分割$ip$地址或者$hh:mm:ss$这样的字符串还算方便

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
char s[100];

int main(void)
{
int h, m, s;
while (~scanf("%d:%d:%d:", &h, &m, &s))
{
printf("%02d:%02d:%02d\n", h, m, s);
}
// int a, b, c, d;
// while (~scanf("%d.%d.%d.%d", &a, &b, &c, &d))
// {
// printf("[%d] [%d] [%d] [%d]\n", a, b, c, d);
// }
return 0;
}

3.strtok

相关头文件:<string.h>

函数原型:char *strtok(char s[], const char *delim),分解字符串为一组字符串。s为要分解的字符,delim为分隔符字符(如果传入字符串,则传入的字符串中每个字符均为分割符)。首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL

个人感觉这个库函数的好处是可以处理一些奇怪的不合法的输入,比如255….255.255.0或者255.5……….这种逗号过多的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <string.h>
char s[100];

int main(void)
{
while (~scanf("%s", s))
{
char *t = strtok(s, ".");
while (t)
{
printf("%s ", t);
t = strtok(NULL, ".");
}
puts("");
}
return 0;
}