在 C 语言中,使用字符串的场景非常多,而字符串的操作也非常频繁。其中一个经典的函数就是 strtok(),它能够将字符串分割成若干个子串,方便我们对字符串进行处理。
本文将深入介绍 strtok() 函数的用法及应用场景,希望能够帮助大家更好地理解这一函数。
一、strtok() 的基础用法
strtok() 函数的语法如下:
```c
char *strtok(char *str, const char *delim);
```
其中,参数 str 是被分割的字符串,参数 delim 是分割字符串的分隔符。
strtok 函数将会将字符串 str 分割成若干个子串,每一个子串都以 delim 中的字符为分隔符,直到遇到空字符为止。
strtok() 函数有一些需要注意的地方:
1. 分割完毕后,strtok() 函数会将原始字符串 str 中的分隔符替换成空字符 '\0',以便于使用者方便处理各个子串。
2. 第一次调用 strtok() 函数时,需要传递字符串 str,后续的调用参数 str 应该为 NULL。这是因为 strtok() 函数会记住上一次分割字符串时的位置。
3. 如果 str 或 delim 为 NULL,则 strtok() 函数返回 NULL。
下面是一个基本的 strtok() 函数的使用示例:
```c
#include
#include
int main()
{
char str[] = "The quick brown fox jumps over the lazy dog";
char *p = strtok(str, " ");
while (p != NULL)
{
printf("%s\n", p);
p = strtok(NULL, " ");
}
return 0;
}
```
上面的代码将会输出以下结果:
```
The
quick
brown
fox
jumps
over
the
lazy
dog
```
二、strtok() 的高级用法
1. 将不同类型的分隔符作为参数
strtok() 函数可以接受多个分隔符,而不仅限于一个。我们可以将多个分隔符定义在等号右边,以逗号隔开。
```c
char str[] = "One,Two;Three.Four/Five,Six|Seven";
char *p = strtok(str, ",;./| ");
while (p != NULL)
{
printf("%s\n", p);
p = strtok(NULL, ",;./| ");
}
```
上面的代码用多个字符定义了分隔符,输出的结果如下:
```
One
Two
Three
Four
Five
Six
Seven
```
2. 分割非常量字符串
除了常量字符串之外,我们还可以分隔非常量字符串。需要注意的是,此时必须在 strtok() 函数内部保存分割字符串的局部状态,否则会出现不可预期的错误。
```c
char str[] = "A:1,B:2,C:3,D:4,E:5,";
char *str_r = str;
char *p = strtok_r(str_r, ",:", &str_r);
while (p != NULL)
{
printf("%s\t%s\n", p, strtok_r(NULL, ",:", &str_r));
p = strtok_r(NULL, ",:", &str_r);
}
```
上面的代码将会输出以下结果:
```
A 1
B 2
C 3
D 4
E 5
```
3. 分割 Unicode 字符串
在 Unicode 环境下,我们需要指定正确的编码格式并使用相应的库函数。在 Windows 下,Universal C Runtime 中包含了宽字符版本的 strtok() 函数:wcstok()。
```c
#include
#include
#include
int main()
{
setlocale(LC_ALL, "");
wchar_t str[] = L"アイス:冰淇淋,烤甜点:お菓子,蛋糕:ケーキ";
wchar_t *wcToken = wcstok(str, L",", &str);
while (wcToken != NULL)
{
printf("%ls\n", wcToken);
wcToken = wcstok(NULL, L",", &str);
}
return 0;
}
```
以上代码将会输出以下结果:
```
アイス:冰淇淋
烤甜点:お菓子
蛋糕:ケーキ
```
三、strtok() 的应用场景
1. 解析 URL
URL 中包含了很多信息,而这些信息都需要进行解析。我们可以利用 strtok() 函数将 URL 分割成若干个部分,再对这些部分进行解析。
以下是一个简单的示例代码:
```c
#include
#include
//解析 URL
int parseUrl(char *url, char *protocol, char *host, char *path)
{
char *p1 = strtok(url, ":");
char *p2 = NULL;
if (p1) //获取协议
{
strncpy(protocol, p1, 16);
protocol[15] = '\0';
}
p1 = strtok(NULL, "/");
if (p1) //获取主机
{
p2 = strchr(p1, ':');
if (p2)
{
*p2++ = '\0';
strncpy(host, p1, 256);
host[255] = '\0';
strncpy(path, p2, 1024);
path[1023] = '\0';
}
else
{
*host = '\0';
strncpy(host, p1, 256);
host[255] = '\0';
*path = '/';
*(path + 1) = '\0';
}
return 0;
}
return -1;
}
int main()
{
char url[] = "http://www.google.com:80/search?q=linux";
char host[256], path[1024], protocol[16];
int ret = parseUrl(url, protocol, host, path);
if (!ret)
{
printf("原始URL:\t%s\n", url);
printf("协议:\t\t%s\n", protocol);
printf("主机:\t\t%s\n", host);
printf("路径:\t\t%s\n", path);
}
return 0;
}
```
以上代码将会输出以下结果:
```
原始URL: http://www.google.com:80/search?q=linux
协议: http
主机: www.google.com
路径: /search?q=linux
```
2. 解析 CSV 文件
CSV 文件是一种常见的数据存储格式,而解析 CSV 文件也是使用 strtok() 函数的一种常见需求。
以下是一个简单的 CSV 文件解析示例:
```c
#include
#include
#include
#define MAX_LINE_LEN 1024
#define MAX_FIELD_LEN 256
#define MAX_FIELD_NUM 1024
//从 CSV 文件中解析出一行数据
int readLine(char *line, char *fields[], int *fieldCount)
{
if (line == NULL || fields == NULL || fieldCount == NULL)
return -1;
char *p = line;
char *pEnd = p + strlen(p);
int i = 0;
while (p < pEnd)
{
char *pDelim = strchr(p, ',');
if (pDelim == NULL)
{
fields[i] = p;
p = pEnd;
}
else
{
*pDelim = '\0';
fields[i] = p;
p = pDelim + 1;
}
i++;
}
*fieldCount = i;
return 0;
}
int main()
{
FILE *fp = fopen("data.csv", "r");
if (fp == NULL)
{
printf("无法打开文件 data.csv\n");
return -1;
}
char line[MAX_LINE_LEN];
char *fields[MAX_FIELD_NUM];
int fieldCount;
while (fgets(line, MAX_LINE_LEN, fp))
{
memset(fields, 0, sizeof(fields));
fieldCount = 0;
readLine(line, fields, &fieldCount);
for (int i = 0; i < fieldCount; i++)
{
if (i != 0)
putchar(',');
printf("%s", fields[i]);
}
putchar('\n');
}
fclose(fp);
return 0;
}
```
假设 data.csv 文件的内容如下:
```
Jack,20,170cm
Peter,34,183cm
Lucy,24,162cm
```
输出的结果将会是:
```
Jack,20,170cm
Peter,34,183cm
Lucy,24,162cm
```
四、总结
strtok() 函数是 C 语言中的一个经典函数,非常适合对字符串进行分割。通过上面的介绍,我们已经了解了 strtok() 函数的基础用法和高级用法。
在实际开发中,我们经常需要使用 strtok() 函数来处理数据。比如,对于 C 程序员来说,经常需要解析命令行参数;对于开发 Web 应用的人员来说,需要经常解析 URL 字符串;对于从 CSV 或者 JSON 文件中读取数据的人员来说,也会常常使用到 strtok() 函数。
最后,希望本文能够对大家了解 strtok() 函数有所帮助。