可以仅在不重叠的字符串上使用strtok函数吗?

时间:2018-12-19 15:23:50

标签: c arrays string

在下面的代码中,字符串数据中有两个子字符串“ on”的实例。但是是否可以仅将strtok应用于不重叠的子字符串“ on”(即不属于另一个单词的一部分)?如果是,请在下面的代码中告诉我如何做以及我做错了什么?

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

int main()
{  
  char data[50]="Jason could you please turn on the TV";
  char delimiter[5]="on";

  char *ptr,*pointer,*pa,*p,*pb[10];
  int i=0,j=0,k=0,count=0;

  p=data;
  pointer=data;

  while((*pointer!='\0')&&(pointer=strstr(pointer,delimiter)))
  {
    pa=pointer+strlen(delimiter);
    ptr=(--pointer);

    while((isspace(*ptr))&&(isspace(*pa)))
    {
      pb[count]=strtok(ptr,delimiter);
      printf("%s\n",pb[count]);
      count++;
      break;

     } 

      pointer++;
     (*pointer)++;

  }   


}

2 个答案:

答案 0 :(得分:2)

Falsestrspn可用于解析匹配单词的字符串。
strcspn将在定界符中每次出现单个字符时拆分字符串。这不太适合您似乎想做的事情。

strtok

编辑:

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

int main() {
    char data[50]="Jason could you please turn on the TV";
    char delimiter[5]="on";
    char *parse = data;
    size_t space = 0;
    size_t span = 0;

    while ( *parse){//parse not pointing to zero terminator
        space = strspn ( parse, " \n\t");//leading whitespace
        parse += space;//advance past whitespace
        span = strcspn ( parse, " \n\t");//not whitespace
        if ( span) {
            printf("word is: %.*s\n", (int)span, parse);//prints span number of characters
        }
        if ( 0 == strncmp ( delimiter, parse, span)) {
            printf ( "\tword matches delimiter: %s\n", delimiter);//found match
        }
        parse += span;//advance past non whitespace for next word
    }
    return 0;
}

可以将基础包装在函数中。这会将原始字符串分为分隔字词所需的尽可能多的子字符串。没有存储任何子字符串,但可以进行修改。

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

int main() {
    char data[50]="Jason could you please turn on the TV";
    char delimiter[5]="on";
    char *parse = data;
    size_t space = 0;
    size_t span = 0;

    while ( *parse){//parse not pointing to zero terminator
        space = strspn ( parse, " \n\t");//leading whitespace
        parse += space;//advance past whitespace
        span = strcspn ( parse, " \n\t");//not whitespace
        if ( span) {
            printf("word is: %.*s\n", (int)span, parse);//prints span number of characters
            if ( 0 == strncmp ( delimiter, parse, span)) {
                printf ( "\tword matches delimiter: %s\n", delimiter);//found match
                *parse = 0;
                parse += span;
                space = strspn ( parse, " \n\t");//leading whitespace
                parse += space;
                break;
            }
        }
        parse += span;//advance past non whitespace for next word
    }
    printf ( "\n\nsplit strings:\n%s\n%s\n", data, parse);
    return 0;
}

编辑

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

char *strwordsep ( char *str, char *word, size_t *stop) {
    char *parse = str;
    size_t space = 0;
    size_t span = 0;

    while ( *parse){//parse not pointing to zero terminator
        space = strspn ( parse, " \n\t");//leading whitespace
        parse += space;//advance past whitespace
        span = strcspn ( parse, " \n\t");//not whitespace
        if ( span) {
            // printf("word is: %.*s\n", (int)span, parse);//prints span number of characters
            if ( 0 == strncmp ( word, parse, span)) {
                // printf ( "\tword matches delimiter: %s\n", word);//found match
                // *parse = 0;//zero terminate
                *stop = parse - str;
                parse += span;//advance past delimiter
                space = strspn ( parse, " \n\t");//leading whitespace
                parse += space;//advance past whiteespace
                return parse;
            }
        }
        parse += span;//advance past non whitespace for next word
    }
    return NULL;
}

int main() {
    char data[]="Jason, I am on the phone, could you please turn on the TV";
    char word[5]="on";
    char *lead = data;
    char *trail = data;
    size_t stop = 0;
    while ( ( trail = strwordsep ( lead, word, &stop))) {
        printf ( "\nsplit strings:\n%.*s\n", (int)stop, lead);
        lead = trail;
    }
    if ( *lead) {
        printf ( "\nsplit strings:\n%s\n", lead);
    }
    return 0;
}

答案 1 :(得分:0)

从您对“ data的意图来看,使用“不重叠”尚不完全清楚,但是我从您希望在{{1}中找到"on"的其他注释中得出结论。 }作为整个单词,而不是data作为"on"的一部分。

当尝试在"Jason"中定位"on"时,您不需要datastrtok, strspn,该作业的正确工具是strcspn,该工具可以您可以找到字符串中子字符串的首次出现。您唯一的工作就是识别要搜索的正确子字符串。

由于在这种情况下,您要对strstr进行全字优化,为什么不搜索"on"来找到" on"并加一个空格。 (您也可以将其扩展为所有空格,但出于句子目的,我们将使用空格分隔的单词,然后扩展对所有空格的检查,以确保"on"之后是空白)。

首先,与"on"的初始化有关,除非您打算在代码中附加到字符串,否则无需指定 magic-number data ,只需将50留空,然后[]的大小将适合于容纳字符串,例如

data

同样,除非您打算更改定界符,否则只需使用 string-literal ,例如

    char data[]="Jason could you please turn on the TV",
        *p = data;    /* pointer to data */

然后在数据中定位 const char *delim = " on"; ,您只需对" on"进行一次调用,就可以在条件表达式中进行调用以确定其是否存在,例如

strstr (p, delim)

如果找到它,只需声明一个指针(或使用 if ((p = strstr (p, delim))) { size_t len = strlen (delim); char *next = p + len; if (isspace (*next) || ispunct (*next)) { printf ("found: '%s' (now what?)\n", ++p); } } 使用数组索引)即可访问p之后的下一个字符。然后,您可以测试" on"之后是否是空格,以确认您已找到所需的子字符串。由于您知道" on"指向p之前的space,因此您可以像上面在{中所做的那样,简单地增加指针"on"指向p本身。 {1}}语句。现在,如何处理字符串的其余部分由您决定。您"on"指向字符串的开头,printf指向p之后的空白,因此可以轻松复制next nul-terminate < / em>在"on"-无论您需要做什么。

将其完全放进去

"on"

使用/输出示例

next

仔细检查一下,如果还有其他问题,请告诉我。

在字符串中查找多个#include <stdio.h> #include <string.h> #include <ctype.h> int main (void) { char data[]="Jason could you please turn on the TV", *p = data; const char *delim = " on"; if ((p = strstr (p, delim))) { size_t len = strlen (delim); char *next = p + len; if (isspace (*next) || ispunct (*next)) { printf ("found: '%s' (now what?)\n", ++p); } } return 0; }

如下面的注释所述,如果您的输入中有多个$ ./bin/strstr_on found: 'on the TV' (now what?) ,则您需要做的就是将上述"on"语句放入循环中,然后设置"on"在循环的末尾。例如,查找以if开头的所有子字符串所需的唯一更改就是:

p = next;

使用/输出查找所有"on"

    char data[]="Jason could you please turn on the TV on the desk",
    ...
    while ((p = strstr (p, delim))) {
        size_t len = strlen (delim);
        char *next = p + len;
        if (isspace (*next) || ispunct (*next)) {
            printf ("found: '%s' (now what?)\n", ++p);
        }
        p = next;
    }

让我知道您是否还有其他问题。