Q我如何将一个字符串分割成以空白符分隔的字段?
我如何复制那个过程,通过这个过程main()被赋予argc和argv?
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