100分求高效分割这种类型字符串

kmsch 2015-10-12 12:59:26
char*类型的字符串,要求以空格分
如果有引号,引号中内容不考虑空格,直接分割出来(分割出来的这一块不再含引号)

如字符串内容为:aaa "bbb ccc" ddd
则分割后需要三个部分:
aaa
bbb ccc
ddd

这有点类似main的传入参数那种,有没现成的函数可以实现,如果没有,烦请大神帮写一个高效的分割函数,谢了
...全文
223 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2015-10-13
  • 打赏
  • 举报
回复
参考《编译原理》中的词法分析和有限状态自动机。
qin522106350 2015-10-13
  • 打赏
  • 举报
回复
char str[] = "aaa \"bbb ccc\" ddd";
  char *p = str;
  char *key_point;
  while(p)
  {
  while ( key_point = strsep(&p,"\x20"))
  {
   if (*key_point == '\"')
{
key_point ++;
*(p-1)=\x20;//修复
strsep(&p,"\"");
}
   else
   break;//分割出一个正常的字符串,快去打印吧!
  }
  printf("%s\n",key_point);
  }
mymtom 2015-10-13
  • 打赏
  • 举报
回复

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

char **
strsplit(const char *str)
{
int size, count;
char **array;
char *item;
const char *head, *tail, *curr;
const char *ptr;
int len;
int quote, word;

size = 4;
array = (char **)malloc(sizeof(char *) * size);

count = 0;
word = 0;
quote = 0;
head = str;
tail = head + strlen(head) + 1;
for (curr = head; curr != tail; ++curr) {
if (word == 0) {
if (*curr == '\"') {
word = 1;
quote = 1;
ptr = curr + 1;
} else if (!isblank(*curr)) {
word = 1;
ptr = curr;
}
} else {
if (quote == 1) {
if (*curr == '\"') {
quote = 2;
}
} else if (quote == 0) {
if (isblank(*curr) || *curr == '\0') {
word = 0;
len = curr - ptr;

if (count + 1 >= size) {
size = size * 2;
array = (char **)realloc(array, sizeof(char *) * size);
}
item = malloc(len + 1);
memcpy(item, ptr, len);
item[len] = '\0';
array[count++] = item;
}
} else if (quote == 2) {
if (isblank(*curr) || *curr == '\0') {
quote = 0;
word = 0;
len = curr - 1 - ptr;

if (count + 1 >= size) {
size = size * 2;
array = (char **)realloc(array, sizeof(char *) * size);
}
item = malloc(len + 1);
memcpy(item, ptr, len);
item[len] = '\0';
array[count++] = item;
}
}
}
}

array[count] = NULL;
return array;
}

void
strfreev(char **array)
{
int i;

if (array) {
for (i = 0; array[i] != NULL; i++)
free(array[i]);
free(array);
}
}

int
main(int argc, char *argv[])
{
int i;
char **array;

array = strsplit("aaa bbb ccc");
for (i = 0; array[i] != NULL; i++)
printf("array[%d]='%s'\n", i, array[i]);
strfreev(array);

array = strsplit(" ddd \t eee \t fff ");
for (i = 0; array[i] != NULL; i++)
printf("array[%d]='%s'\n", i, array[i]);
strfreev(array);

array = strsplit("xxx \"yyy yyy\" zzz");
for (i = 0; array[i] != NULL; i++)
printf("array[%d]='%s'\n", i, array[i]);
strfreev(array);

array = strsplit("abcd efg \"hijk lmn\" opq rst \"uvw xyz\"");
for (i = 0; array[i] != NULL; i++)
printf("array[%d]='%s'\n", i, array[i]);
strfreev(array);

return 0;
}

/* output
array[0]='aaa'
array[1]='bbb'
array[2]='ccc'
array[0]='ddd'
array[1]='eee'
array[2]='fff'
array[0]='xxx'
array[1]='yyy yyy'
array[2]='zzz'
array[0]='abcd'
array[1]='efg'
array[2]='hijk lmn'
array[3]='opq'
array[4]='rst'
array[5]='uvw xyz'
*/
赵4老师 2015-10-13
  • 打赏
  • 举报
回复
言之有理。
kmsch 2015-10-13
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
仅供参考:
//aaa  "bbb ccc"  ddd
//则分割后需要三个部分:
//aaa
//bbb ccc
//ddd
#include <stdio.h>
int par(char **s,int *L) {
    int st;
    char *p=*s;

    st=0;
    while (1) {
        switch (st) {
        case 0:
                 if (*p==0   ) return 0;
            else if (*p==' ' );
            else if (*p=='\"') {*s=p+1;*L=0;st=2;}
            else {*s=p;*L=1;st=1;}
        break;
        case 1:
                 if (*p==0   ) return 1;
            else if (*p==' ' ) return 1;
            else if (*p=='\"') {printf("error");return 0;}
            else (*L)++;
        break;
        case 2:
                 if (*p==0   ) {printf("error");return 0;}
            else if (*p=='\"') {st=0;return 1;}
            else (*L)++;
        break;
        }
        p++;
    }
}
int main() {
    char *str="aaa  \"bbb ccc\"  ddd";
    char *p;
    int r,n;

    p=str;
    while (1) {
        r=par(&p,&n);
        if (r==0) break;
        printf("[%.*s]\n",n,p);
        p+=n;
        if (p[0]=='\"') p++;
    }

    return 0;
}
//[aaa]
//[bbb ccc]
//[ddd]
//
这种方法我觉得挺好,谢谢 另外: case 2: if (*p==0 ) {printf("error");return 0;} else if (*p=='\"') {st=0;return 1;} else (*L)++; 这里我觉得没必要st=0;这句,因为st是局部变量,之后就返回了
707wk 2015-10-12
  • 打赏
  • 举报
回复

#include <stdio.h>

/*
aaa "bbb ccc" ddd
*/

int main()
{
int flage=0 ;
char ch;
for(;;)
{
ch=getchar();
if(ch=='\n')break ;
switch(ch)
{
case '\"' :
flage=!flage ;
break ;
case ' ' :
if(!flage)printf("\n");
else printf(" ");
break ;
default :
printf("%c",ch);
break ;
}
}

return 0 ;
}
只是输出而已
勤奋的小游侠 2015-10-12
  • 打赏
  • 举报
回复
先将引号的分出来,然后剩下的按空格分。
你说要高效,这个还真不知道如何才能高效。
shen_wei 2015-10-12
  • 打赏
  • 举报
回复
现查找 " 然后就是配对 " 然后就是查找空格。。
赵4老师 2015-10-12
  • 打赏
  • 举报
回复
仅供参考:
//aaa  "bbb ccc"  ddd
//则分割后需要三个部分:
//aaa
//bbb ccc
//ddd
#include <stdio.h>
int par(char **s,int *L) {
int st;
char *p=*s;

st=0;
while (1) {
switch (st) {
case 0:
if (*p==0 ) return 0;
else if (*p==' ' );
else if (*p=='\"') {*s=p+1;*L=0;st=2;}
else {*s=p;*L=1;st=1;}
break;
case 1:
if (*p==0 ) return 1;
else if (*p==' ' ) return 1;
else if (*p=='\"') {printf("error");return 0;}
else (*L)++;
break;
case 2:
if (*p==0 ) {printf("error");return 0;}
else if (*p=='\"') {st=0;return 1;}
else (*L)++;
break;
}
p++;
}
}
int main() {
char *str="aaa \"bbb ccc\" ddd";
char *p;
int r,n;

p=str;
while (1) {
r=par(&p,&n);
if (r==0) break;
printf("[%.*s]\n",n,p);
p+=n;
if (p[0]=='\"') p++;
}

return 0;
}
//[aaa]
//[bbb ccc]
//[ddd]
//

64,642

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧