user-0 提问: 字符串切割函数的应用

回复:
user: user-1
content: 仅供参考#include <stdio.h> #include <string.h> char string[80]; char seps1[3]; char seps2[3]; char *token; char *zzstrtok (     char *string,     const char *control1,//连续出现时视为中间夹空token     const char *control2 //连续出现时视为中间无空token     ) {     unsigned char *str;     const unsigned char *ctrl1 = control1;     const unsigned char *ctrl2 = control2;     unsigned char map1[32],map2[32];     static char *nextoken;     static char flag=0;     unsigned char c;     int L;      memset(map1,0,32);     memset(map2,0,32);     do {         map1[*ctrl1 >> 3] |= (1 << (*ctrl1 & 7));     } while (*ctrl1++);     do {         map2[*ctrl2 >> 3] |= (1 << (*ctrl2 & 7));     } while (*ctrl2++);      if (string) {         if (control2[0]) {             L=strlen(string);             while (1) {                 c=string[L-1];                 if (map2[c >> 3] & (1 << (c & 7))) {                     L--;                     string[L]=0;                 } else break;             }         }         if (control1[0]) {             L=strlen(string);             c=string[L-1];             if (map1[c >> 3] & (1 << (c & 7))) {                 string[L]=control1[0];                 string[L+1]=0;             }         }         str=string;     }     else        str=nextoken;      string=str;     while (1) {         if (0==flag) {             if (!*str) break;             if (map1[*str >> 3] & (1 << (*str & 7))) {                 *str=0;                 str++;                 break;             } else if (map2[*str >> 3] & (1 << (*str & 7))) {                 string++;                 str++;             } else {                 flag=1;                 str++;             }         } else if (1==flag) {             if (!*str) break;             if (map1[*str >> 3] & (1 << (*str & 7))) {                 *str=0;                 str++;                 flag=0;                 break;             } else if (map2[*str >> 3] & (1 << (*str & 7))) {                 *str=0;                 str++;                 flag=2;                 break;             } else str++;         } else {//2==flag             if (!*str) return NULL;             if (map1[*str >> 3] & (1 << (*str & 7))) {                 str++;                 string=str;                 flag=0;             } else if (map2[*str >> 3] & (1 << (*str & 7))) {                 str++;                 string=str;             } else {                 string=str;                 str++;                 flag=1;             }         }     }     nextoken=str;      if (string==str) return NULL;     else             return string; } void main() {    strcpy(string,"A \tstring\t\tof ,,tokens\n\nand some  more tokens, ");    strcpy(seps1,",\n");strcpy(seps2," \t");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"1234| LIYI|China | 010 |201110260000|OK");    strcpy(seps1,"|");strcpy(seps2," ");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"1234|LIYI||010|201110260000|OK");    strcpy(seps1,"");strcpy(seps2,"|");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"1234|LIYI||010|201110260000|OK");    strcpy(seps1,"|");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"a");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"a,b");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"a,,b");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",a");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"a,");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",a,,b");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",,a,,b,,");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",,");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",,,");    strcpy(seps1,",");strcpy(seps2," ");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    } } // //[A      string          of ,,tokens // //and some  more tokens, ] //Tokens: // <A> <string> <of> <> <tokens> <> <and> <some> <more> <tokens> <> //[1234| LIYI|China | 010 |201110260000|OK] //Tokens: // <1234> <LIYI> <China> <010> <201110260000> <OK> //[1234|LIYI||010|201110260000|OK] //Tokens: // <1234> <LIYI> <010> <201110260000> <OK> //[1234|LIYI||010|201110260000|OK] //Tokens: // <1234> <LIYI> <> <010> <201110260000> <OK> //[a] //Tokens: // <a> //[a,b] //Tokens: // <a> <b> //[a,,b] //Tokens: // <a> <> <b> //[,a] //Tokens: // <> <a> //[a,] //Tokens: // <a> <> //[,a,,b] //Tokens: // <> <a> <> <b> //[,,a,,b,,] //Tokens: // <> <> <a> <> <b> <> <> //[,] //Tokens: // <> <> //[,,] //Tokens: // <> <> <> //[,,,] //Tokens: // <> <> <> <>

user: user-1
content: 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。

user: user-0
content: 代码整体的流程如下：  （1）判断参数s是否为NULL，如果是NULL就以传递进来的saveptr作为起始分解位置；若不是NULL，则以s开始切分。  （2）跳过待分解字符串开始的所有分界符。  （3）判断当前待分解的位置是否为'/0'，若是则返回NULL（联系到（一）中所说对返回值为NULL的解释）；不是则继续。  （4）保存当前的待分解串的指针token，调用strpbrk在token中找分界符：如果找不到，则将saveptr赋值为待分解串尾部'/0'所在的位置，token没有发生变化；若找的到则将分界符所在位置赋值为'/0'，token相当于被截断了（提取出来），saveptr指向分界符的下一位。  （5）函数的最后（无论找到还是没找到）都将返回。      这就是strtokr函数功能

user: user-0
content: 没写注释见谅

user: user-2
content: #include<stdio.h> #include<stdlib.h> #include<string.h> char *strtokr(char *s,char *Delim,char **saveptr) { 	char *token=NULL; 	if(s==NULL) 	{ 		s=*saveptr; 	} 	s=s+strspn(s,Delim);   	if(*s=='\0') 	{ 		return NULL; 	} 	token=s; 	s=strpbrk(token,Delim); 	if(s==NULL) 	{ 		*saveptr=strchr(token,'\0'); 	} 	else 	{ 		*s='\0'; 		*saveptr=s+1; 	} 	return token; }  void Initial(char **p) { 	int i=0; 	for(i=0;i<20;i++) 	{ 		*(p+i)=NULL; 	} }  int main() { 	char s[100]="012 jiangcai english 100,013 lilei english 12,014 xiaohua english 90"; 	int i=0; 	char **outsaveptr=NULL; 	char **insaveptr=NULL; 	char **p=(char **)malloc(20*sizeof(char *)); 	char **q=p; 	char *buf=s; 	Initial(p); 	while(*q=strtokr(buf,",",outsaveptr)) 	{ 		buf=*q; 		while(*q=strtokr(buf," ",insaveptr)) 		{ 			q++; 			buf=NULL; 		} 		buf=NULL; 	} 	for(i=0;(*(p+i)!=NULL);i++) 	{ 		printf("%s\n",*(p+i)); 	}     	system("pause"); 	free(q); 	free(p); 	p=NULL;  	q=NULL; 	outsaveptr=NULL; 	insaveptr=NULL;  	return 0; }   我在vs2010中把楼主的程序格式调整了一下，这样看程序可能会懂得快些…… 楼主的程序编译没错，运行会崩~~~ 楼主的程序能不能说一下功能？？多一点变量和语句功能的注释，这让人也看得容易查错？？？

user: user-0
content: 警告 i.cpp 39: 可能是不正确的赋值在 main 函数中 警告 i.cpp 41: 可能是不正确的赋值在 main 函数中 以上两条就是全部错误信息

user: user-3
content: char **p=(char **)malloc(20*sizeof(char *));  char **q=p;  char *buf=s;  我觉得这块有问题！C语言必须把所有的变量定义写在开头！  其次楼主要注意编码风格！ 看着很DT

user: user-3
content: 楼主错误信息是什么？可否贴出错误信息让在下看下？

user: user-0
content: 没分配内存怎么改动

user: user-4
content: char **outsaveptr=NULL;   //没有分配内存   在函数中 else 	{ 		*s='\0'; 		*saveptr=s+1;  //这里没有分配内存    对*saveptr必然崩溃  	}