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

1 strchr

1.1 描述

strchr() 用于查找字符串中的一个字符,并返回该字符在字符串中第一次出现的位置。其原型定义在头文件 中。
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 #include 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(一个无符号字符)的位置。其原型定义在头文件 中。

2.2 声明

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

2.3 实例
#include #include 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 #include #includeint 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 #include #includeint 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 #include #includeint main(){// Our input stringchar input_string[] = "https:/10.229.89.210/home/data/1.txt";// Our output token listchar **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 NULLchar *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 futurechar *token = strtok_r(input_string, "/", &context);int num_tokens = 0; // Index to token list. We will append to the listwhile (token != NULL){// Keep getting tokens until we receive NULL from strtok()token_list[num_tokens] = strdup(token); // Copy to token listnum_tokens++;token = strtok_r(NULL, "/", &context); // We pass the context variable to strtok_r}// Print the list of tokensprintf("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 ()