C语言 字符串解析strchr/strrchr/strtok//strtok_r函数使用

在程序中,解析用户输入的参数(命令行参数)是很常见的操作,本文将讲解C语言中常见的一些解析字符串函数使用方法。

1 strchr

1.1 描述

strchr() 用于查找字符串中的一个字符,并返回该字符在字符串中第一次出现的位置。其原型定义在头文件 <string.h> 中。
char *strchr(const char *str, int c) 在参数 str 所指向的字符串中搜索第一次出现字符 c(一个无符号字符)的位置。
strchr() 函数返回的指针指向字符串中的字符,如果要将该指针用作字符串,应该将其传递给其他字符串处理函数,例如 printf() 或 strncpy()。

1.2 声明

char *strchr(const char *str, int c)
str – 要查找的字符串。
c – 要查找的字符。
如果在字符串 str 中找到字符 c,则函数返回指向该字符的指针,如果未找到该字符则返回 NULL。

1.3 实例
#include <stdio.h>
#include <string.h>

int main()
{
    const char *str = "https://10.229.89.210/home/data/1.txt";
    const char ch = 'd';
    char *ptr;

    ptr = strchr(str, ch);

    if (ptr != NULL)
    {
        printf("字符 '%c 出现的位置为 %ld。\n",ch,  ptr - str + 1);
        printf("|%c| 之后的字符串是 - |%s|\n", ch, ptr);
    }
    else
    {
        printf("没有找到字符 'd' 。\n");
    }
    return (0);
}

2 strrchr
2.1 描述

char *strrchr(const char *str, int c) 在参数 str 所指向的字符串中搜索最后一次出现字符 c(一个无符号字符)的位置。其原型定义在头文件 <string.h> 中。

2.2 声明

char *strrchr(const char *str, int c)
str – C 字符串。
c – 要搜索的字符。以 int 形式传递,但是最终会转换回 char 形式。
返回值
该函数返回 str 中最后一次出现字符 c 的位置。如果未找到该值,则函数返回一个空指针

2.3 实例
#include <stdio.h>
#include <string.h>

int main()
{
    const char *str = "https://10.229.89.210/home/data/1.txt";
    const char ch = '/';
    char *ptr;

    ptr = strrchr(str, ch);

    if (ptr != NULL)
    {
        printf("字符 '%c 出现的位置为 %ld。\n",ch,  ptr - str + 1);
        printf("|%c| 之后的字符串是 - |%s|\n", ch, ptr);
    }
    else
    {
        printf("没有找到字符 'd' 。\n");
    }
    return (0);
}

3 strtok
3.1 描述

char *strtok(char *str, const char *delim) 分解字符串 str 为一组字符串,delim 为分隔符。

3.2 声明

char *strtok(char *str, const char *delim)
str – 要被分解成一组小字符串的字符串。
delim – 包含分隔符的 C 字符串。
该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。

3.3 实例

3.3.1 实例1

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

int main()
{
    char *str = "https://10.229.89.210/home/data/1.txt";

    char *str1 = malloc(sizeof(char) * (strlen(str) + 1));
    strcpy(str1, str);
    const char ch = '/';
    char *ptr;
    char *ptr1;
    ptr = strtok(str, ":");
    //ptr1 = strtok(str1, ":");

    if (ptr != NULL)
    {
    //   printf("%s\n", str);     // strtok会修改
       printf("%s\n", ptr);
    //   printf("\n%s\n\n", ptr1);
    //   printf("\n|%c| 之后的字符串是 - |%s|\n\n", ch, ptr);
    }
    else
    {
        printf("\n没有找到字符 'd' 。\n");
    }
    return (0);
}
结果:段错误 (核心已转储)

3.3.2 实例2

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

int main()
{
    char *str = "https://10.229.89.210/home/data/1.txt";

    char *str1 = malloc(sizeof(char) * (strlen(str) + 1));
    strcpy(str1, str);
    // char str2[64]; strcpy(str2, str);   ==> 数组也可以,如果不习惯 malloc/free匹对使用
    const char ch = '/';
    char *ptr;
    char *ptr1;
    //ptr = strtok(str, ":");
    ptr1 = strtok(str1, ":");

    if (ptr1 != NULL)
    {
    //   printf("%s\n", str);     // strtok会修改str参数值
    //   printf("%s\n", ptr);
       printf("\n%s\n\n", ptr1);
    //   printf("\n|%c| 之后的字符串是 - |%s|\n\n", ch, ptr);
    }
    else
    {
        printf("\n没有找到字符 'd' 。\n");
    }
	free(str1);
    return (0);
}
结果正确: https
4 strtok_r

4.1 声明
char *strtok_r(char *str, const char *delim, char **saveptr);
函数的返回值是 排在前面的 被分割出的字串,或者为NULL,
str是传入的字符串。需要注意的是 :第一次使用strtok_r之后,要把str置为NULL,
delim指向依据分割的字符串。常见的空格“ ” 逗号“,”等
saveptr保存剩下待分割的字符串。

比如:按空格分割 字符串 “first second third”,

分第一次得字串”first”,然后saveptr指向了”second third”

分第2次得字串”second”,然后saveptr指向了”third”
分第3次得字串”third”,然后saveptr指向了NULL
结束。

#include <stdio.h>
#include <string.h>
#include<stdlib.h>
int main()
{
    // Our input string
    char input_string[] = "https:/10.229.89.210/home/data/1.txt";

    // Our output token list
    char **token_list = NULL;
    token_list = (char **)malloc(sizeof(char *) * 64);


    // A pointer, which we will be used as the context variable
    // Initially, we will set it to NULL
    char *context = NULL;

    // To get the value of the context variable, we can pass it's address
    // strtok_r() to automatically populate this context variable, and refer
    // it's context in the future
    char *token = strtok_r(input_string, "/", &context);

    int num_tokens = 0; // Index to token list. We will append to the list

    while (token != NULL)
    {
        // Keep getting tokens until we receive NULL from strtok()
        token_list[num_tokens] = strdup(token); // Copy to token list
        num_tokens++;
        token = strtok_r(NULL, "/", &context); // We pass the context variable to strtok_r
    }

    // Print the list of tokens
    printf("Token List:\n");
    for (int i = 0; i < num_tokens; i++)
    {
        printf("%s\n", token_list[i]);
    }
    free(token_list);
    return 0;
}

参考链接:
1 strtok函数缺陷再探
2 strtok () 和 strtok_r ()

版权声明:本文为博主作者:Serendipity_Shy原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/qq_52668274/article/details/130167057

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2024年1月3日
下一篇 2024年1月3日

相关推荐

此站出售,如需请站内私信或者邮箱!