【C 语言基础】以空格分割字符串

方法一、 使用<string.h>的strtok()

函数原型: char *strtok(char *str1, const char *str2);

头文件:#include <string.h>

功能: 用指定的分隔符分解字符串

参数:  

  • char *str1  为要分解的字符串
  • const char *str2  为分隔符字符串

返回值:  返回下一个分割后的(位于最开始的)字符串指针,如果已无从分隔,则返回NULL

程序例: 将字符串数组input通过分隔符" "(空格)分隔开,并将结果输出。

#include <stdio.h>
#include <string.h>

int main(void){   
    char input[50] = "I like www.dotcpp.com very much";
    char *p = strtok(input, " ");
    
    if(p){
        printf("%s\n", p);
    }
    while(p=strtok(NULL, " ")){//使用第一个参数为NULL来提取子串
        printf("%s\n", p);
    }
    return 0;
}

运行结果:

I
like
www.dotcpp.com
very
much

注意:

1、函数的作用是分解字符串,所谓分解,即没有生成新串,只是在s所指向的内容首次出现分界符的位置,将分界符修改成了'/0’,故第一次用strtok()返回第一个子串

2、第一次提取子串完毕之后,继续对源字符串s进行提取,应在其后(第二次,第三次。。。第n次)的调用中将strtok的第一个参数赋为空值NULL(表示函数继续从上一次调用隐式保存的位置,继续分解字符串)

这里可以称这个隐式保存的位置为返回值(注意,它不是下面所说的this指针)

对于前一次次调用来说,第一次调用结束前用一个this指针指向了分界符的下一位。

3、当this指针 隐式保存的位置 指向“\0” 时,即没有被分割的子串了,此时则返回NULL

4、可以把delim理解为分隔符的集合,delim中的字符均可以作为分隔符。

5、strtok在调用的时候,如果起始位置即为分隔符,则忽略了起始位置开始的分隔符

6、该函数会改变str1的值,所以str1必须是字符串数组,不能是字符串指针!!!!

                        

方法二、 使用<stdio.h>的sscanf()+正则表达式

【原型】int sscanf (char *str, char * format [, argument, ...]);

【参数】

  • 参数str为要读取数据的字符串;
  • format为用户指定的格式;(可以指定为正则表达式,也可以是普通的%d, %c等等)
  • argument为变量,用来保存读取到的数据。

【返回值】成功则返回参数数目,失败则返回-1,错误原因存于errno 中。

sscanf()会将参数str 的字符串根据参数format(格式化字符串)来转换并格式化数据(格式化字符串请参考scanf()), 转换后的结果存于对应的变量中。

sscanf()与scanf()类似,都是用于输入的,只是scanf()以键盘(stdin)为输入源,sscanf()以固定字符串为输入源。

【实例】从指定的字符串中读取整数和小写字母

#include <stdio.h>

int main()
{
    char str[] = "123568qwerSDDAE";
    
    
    //===================== 模式匹配 ==========================  
    int num;
    char lowercase[10];
    sscanf(str,"%d%[a-z]", &num, lowercase);
    printf("The number is: %d\n", num);
    printf("The lowercase is: %s\n", lowercase);
  
    //===================== 分割字符串(模式匹配的特例) ==========================  
    int a, b, c;
    sscanf("2006:03:18", "%d:%d:%d", &a, &b, &c);
    printf("a: %d, b: %d, c: %d\n", a, b, c);
    char time1[20];
    char time2[20];
    sscanf("2006:03:18 - 2006:04:18", "%s - %s", time1, time2);
    printf("time1: %s, time2: %s\n", time1, time2);
    return 0;
}

运行结果:

可以看到format参数有些类似正则表达式(当然没有正则表达式强大,复杂字符串建议使用正则表达式处理),支持集合操作,例如:

  • %[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
  • %[aB'] 匹配a、B、'中一员,贪婪性
  • %[^a] 匹配非a的任意字符,贪婪性

另外,format不仅可以用空格界定字符串,还可以用其他字符界定,可以实现简单的字符串分割(更加灵活的字符串分割请使用strtok() 函数),例如在Web服务器解析HTTP请求时,可以写如下代码。

char *input;

char type[16] = {0};//HTTP请求类型,一般为GET或者POST
char path[128] = {0};//请求的文件名
char protocol[16] = {0};//HTTP协议版本号,常用为HTTP/1.1

sscanf(input, "%[^ ] %[^ ] %[^ ]", type, path, protocol);

 

 

 

1. strtok()原文链接:https://blog.csdn.net/weixin_34324082/article/details/113561523

2. sscanf()原文链接:https://blog.csdn.net/weixin_39756895/article/details/113028865

posted @ 2024-03-12 21:56  FBshark  阅读(1110)  评论(0编辑  收藏  举报