• 字符串分割


    gets(str)=scanf("%[^ ]",str);

    B - 排序

    输入一行数字,如果我们把这行数字中的‘5’都看成空格,那么就得到一行用空格分割的若干非负整数(可能有些整数以‘0’开头,这些头部的‘0’应该被忽略掉,除非这个整数就是由若干个‘0’组成的,这时这个整数就是0)。 

    你的任务是:对这些分割得到的整数,依从小到大的顺序排序输出。

    Input

    输入包含多组测试用例,每组输入数据只有一行数字(数字之间没有空格),这行数字的长度不大于1000。   
    输入数据保证:分割得到的非负整数不会大于100000000;输入数据不可能全由‘5’组成。

     Output

    对于每个测试用例,输出分割得到的整数排序的结果,相邻的两个整数之间用一个空格分开,每组输出占一行。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 1010;
     4 char s[maxn];
     5 int a[maxn], ans;
     6 char *p;
     7 int v;
     8 
     9 int main() {
    10     while(gets(s)) {
    11         ans = 0;
    12         p = strtok(s, "5");//(地址,"分隔符")
    13         while(p){
    14             sscanf(p, "%d", &v);//把 p 写入 v
    15             a[ans++] = v;
    16             p = strtok(NULL, "5");//第二次调用NULL
    17         }
    18         sort(a, a+ans);
    19         for(int i=0;i<ans;i++) {
    20             if(i == 0)
    21                 printf("%d", a[i]);
    22             else
    23                 printf(" %d", a[i]);
    24         }
    25         printf("
    ");
    26     }
    27 }

    字符串分割函数strtok(会改变原字符串)

    头文件:#include <cstring>

    函数原型:char *strtok(char *str, const char *delimiters);

    函数功能:分割字符串,将str分割成一个个子串

    函数参数:

           str: 在第一次被调用的时候str传入需要被分割字符串的首地址;在后面调用的时候传入NULL。

           delimiters: 表示分割字符串中包含的所有字符。

    函数返回值:

           当s中的字符查找到末尾时,返回NULL;

           如果查不到delimiters所标示的字符,则返回当前strtok的字符串的指针。

    需要注意的是:使用该函数进行字符串分割时,会破坏并分解字符串的完整,调用前和调用后的str已经不一样了。strtok在切割字符串的时候,实际上就是将分割符的字符delimiter替换为''并且返回首地址。这点在下面会有例子说明。

    例一:分割单个字符
    (1)将字符串通过'@'分割开:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3  
     4 int main()
     5 {
     6     char str[] = "@I am@a great@young man@!";
     7     char *temp = strtok(str, "@");
     8     while (temp)
     9     {
    10         cout << temp << endl;
    11         temp = strtok(NULL, "@");
    12     }
    13  
    14     return 0;
    15 }

    运行结果:

           I am
           a great
           young man
           !

    (2)下面我们来观察一下调用strtok()函数之后的str会是什么样的:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3  
     4 int main()
     5 {
     6     char str[] = "@I am@a great@young man@!";
     7     char *temp = strtok(str, "@");
     8     while (temp)
     9     {
    10         cout << temp << endl;
    11         temp = strtok(NULL, "@");
    12     }
    13     
    14     for (int i = 0; i < sizeof(str); i++)
    15         cout << str[i];
    16     return 0;
    17 }

    我们发现调用完strtok函数后再输出的完整的str是:

           @I am a great young man !

    例一总结:strtok在分割字符串的过程,实际上就是将被分割的字符串的分割字符替换为'' 并且返回标记字符串的首地址,直到返回NULL结束。调用完strtok后,如果只是直接输出str,而不是像上面一样将所有的字符都输出,则输出的是@I am。但需要注意的是,此处有点特殊,因为有一个分割符在字符串首位,所以第一个@没被替换,后面的@全部被替换;但如果第一位不是分割字符,则后面的分割符也是全部被替换为'',而不是第一个分割符不被替换。

    例二:分割多个字符
    将字符串通过'@'和'!'分割开:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3  
     4 int main()
     5 {
     6     char str[] = "I!am@a!great@young!man.!";
     7     char *temp = strtok(str, "@!");
     8     while (temp)
     9     {
    10         cout << temp << endl;
    11         temp = strtok(NULL, "@!");
    12     }
    13     
    14     return 0;
    15 }


    可以看出,只需要将分割字符全部放到一个字符串里即可,如"@!"。

    1.定义
    分解字符串为一组字符串。s为要分解的字符,delim为分隔符字符(如果传入字符串,则传入的字符串中每个字符均为分割符)。首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL。在头文件#include<string.h>中。
    2.原型
    char *strtok(char s[], const char *delim);
    3.说明
    (1)当strtok()在参数s的字符串中发现参数delim中包含的分割字符时,则会将该字符改为 字符。在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。每次调用成功则返回指向被分割出片段的指针。
    (2)返回值

    从s开头开始的一个个被分割的串。当s中的字符查找到末尾时,返回NULL。如果查找不到delim中的字符时,返回当前strtok的字符串的指针。所有delim中包含的字符都会被滤掉,并将被滤掉的地方设为一处分割的节点。

    (3)需要注意的是,使用该函数进行字符串分割时,会破坏被分解字符串的完整,调用前和调用后的s已经不一样了。第一次分割之后,原字符串str是分割完成之后的第一个字符串,剩余的字符串存储在一个静态变量中,因此多线程同时访问该静态变量时,则会出现错误。

    4.使用
    strtok函数会破坏被分解字符串的完整,调用前和调用后的s已经不一样了。如果要保持原字符串的完整,可以使用strchr和sscanf的组合等。

    5、strtok_s函数

    strtok_s是windows下的一个分割字符串安全函数,其函数原型如下:
    char *strtok_s( char *strToken, const char *strDelimit, char **buf);
    这个函数将剩余的字符串存储在buf变量中,而不是静态变量中,从而保证了安全性。

    6、strtok_r函数
    strtok_r函数是linux下分割字符串的安全函数,函数声明如下:
    char *strtok_r(char *str, const char *delim, char **saveptr);
    该函数也会破坏带分解字符串的完整性,但是其将剩余的字符串保存在saveptr变量中,保证了安全性。

    要使用strtok函数需要包含头文件string.h

    #include <string.h>  
    strtok函数的作用是把字符串以规定的字符分割开:

    p = strtok(buf, "$"); 

    p为指针,buf也是指针,这句代码的意思就是把buf中的字符串以"$"为分隔符分割开来,分割出来的字符串保存到指针p中。
    再次调用strtok函数时,把buf换成NULL,不需要再写buf。即:

    p = strtok(NULL, "$"); 

    需要注意的是,strtok函数会把分割前的字符串破坏掉,即每次分割后,原来的字符串就会少掉一部分,完整性会被破坏。

    while循环离有一个判断p是否等于NULL的语句是因为strtok函数分割到最后没东西分的时候会返回一个空指针,所以需要加个判断跳出循环,否则就会出现段错误。这里也让我知道了,对于指针的使用前面必须加判断,判断是否为空指针,如为空指针需要报错,否则出现段错误都不知道是哪里出错。strtok函数的分隔字符还可以是多个,不一定只为一个

    p = strtok(buf, "$,"); 

    这句代码的意思是以"$"和","为分隔符分割buf中的字符串。每当遇到这两个字符其中一个都会分割,不是遇到"$,"两个字符连在一起才分割,记住只需要遇到其中一个字符就可以了,这样对于函数的使用人性化很多。

     1 p = strtok(buf, "$");  
     2  
     3 while( p!=NULL )
     4 {  
     5     
     6 p = strtok(NULL, "$");  
     7     
     8 if( p==NULL )
     9   {   
    10    break;    
    11  
    12   }  
    13  
    14 } 

    strtok函数是一个非常好用的字符串处理函数,会用这个函数对编程会有非常大的帮助。

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <sstream>
     5 #include <vector>
     6 #include <algorithm>
     7 
     8 using namespace std;
     9 
    10 int main()
    11 {
    12     string str;
    13     while(cin>>str)
    14     {
    15         int tem;
    16         int num=0;
    17         vector<int> vi;
    18         for(int i=0;i<str.size();i++)
    19         {
    20             if(str[i]=='5')
    21                 str[i]=' ';
    22         }
    23         istringstream is(str);
    24         while(is>>tem)
    25         {
    26             num++;
    27             vi.push_back(tem);
    28         }
    29         sort(vi.begin(),vi.begin()+num);
    30         for(int i=0;i<num;i++)
    31         {
    32             if(i==0)
    33                 printf("%d",vi[i]);
    34             else printf(" %d",vi[i]);
    35         }
    36         printf("
    ");
    37     }
    38     return 0;
    39 }
  • 相关阅读:
    设计模式 --单例模式
    Neor Profile SQL 中文汉化
    office online server 安装部署整合到到C#项目
    C# 线程池
    WinForm版 屏幕截图
    golang-nsq高性能消息队列
    【Go Time】Go语言里的条件语句else、switch
    【Go Time】Go语言常量定义关键字const
    【Go Time】Go定义变量
    【Go Time】Go语言里的空接口
  • 原文地址:https://www.cnblogs.com/jiamian/p/11160716.html
Copyright © 2020-2023  润新知