prev up next   top/contents search

comp.lang.c FAQ 列表· 问题 13.6

Q我如何将一个字符串分割成以空白符分隔的字段?
我如何复制那个过程,通过这个过程main()被赋予argcargv?


A对于这种“分词”来说,唯一可用的标准函数是strtok,尽管它使用起来可能很棘手 [脚注],并且它可能无法完成你想要的一切。(例如,它不处理引号。)下面是一个使用示例,它仅仅打印出每个被提取出来的字段。

#include <stdio.h>
#include <string.h>
char string[] = "this is a test";	/* not char *; see Q 16.6 */
char *p;
for(p = strtok(string, " \t\n"); p != NULL;
			p = strtok(NULL, " \t\n"))
	printf("\"%s\"\n", p);

作为替代,这里有一个我用来构建一个argv一次性完成

#include <ctype.h>

int makeargv(char *string, char *argv[], int argvsize)
{
	char *p = string;
	int  i;
	int argc = 0;

	for(i = 0; i < argvsize; i++) {
		/* skip leading whitespace */
		while(isspace(*p))
			p++;

		if(*p != '\0')
			argv[argc++] = p;
		else {
			argv[argc] = 0;
			break;
		}

		/* scan over arg */
		while(*p != '\0' && !isspace(*p))
			p++;
		/* terminate arg: */
		if(*p != '\0' && i < argvsize-1)
			*p++ = '\0';
	}

	return argc;
}

调用makeargv很简单

	char *av[10];
	int i, ac = makeargv(string, av, 10);
	for(i = 0; i < ac; i++)
		printf("\"%s\"\n", av[i]);

如果你希望每个分隔符字符都有意义,例如,如果你希望连续的两个制表符表示一个省略的字段,那么使用strchr:

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

char string[] = "this\thas\t\tmissing\tfield";
char *p = string;

while(1) {		/* break in middle */
	char *p2 = strchr(p, '\t');
	if(p2 != NULL)
		*p2 = '\0';
	printf("\"%s\"\n", p);
	if(p2 == NULL)
		break;
	p = p2 + 1;
}

可能更简单。所有这里提供的代码片段都会修改输入字符串,通过插入\0's' 来终止每个字段(这意味着字符串必须是可写的;参见问题 1.32)。如果你稍后还需要原始字符串,请在分割它之前先复制一份。

参考:K&R2 Sec. B3 p. 250
ISO Sec. 7.11.5.8
H&S Sec. 13.7 pp. 333-4
PCS p. 178


prev up next   contents search
关于此 FAQ 列表   关于 Eskimo   搜索   反馈   版权

Eskimo North 托管