首页 > 解决方案 > 从字符串中获取标记并更改字符串

问题描述

我想将一个字符串分成更小的字符串,并在此过程中更改输入字符串。

例如 -> 输入:嗨,我的名字是

我想获得第一个令牌(嗨),从一个函数中返回它,并在同一个函数中将我的字符串更改为:我的名字是

然后,下一次迭代函数返回“my”,字符串变为“name is”

就像是:

char * tokeniz(char * str){
    char * token;

    token = strtok(str," ");

    /* eliminate the token from the input string */

    return token;
}

main(){

    char *tok;
    char *s=malloc(sizeof(char)*100);

    fgets (s, 100, stdin);

    loop {
        tok=tokeniz(s);
        func_do_something_with_tok();
    }
}

请注意,在返回下一次迭代时,必须在主函数中更改输入字符串 's'

标签: cstring

解决方案


This is an interesting request: breaking a string in place into tokens without allocation or static state.

Here is a method:

  • You can scan the argument string to determine the substring to return and the new start of the argument string.
  • If no new token, return NULL
  • Copy the token to a temporary block of memory
  • Move the contents of the string in place for the new start to appear at the start.
  • Copy the saved token after the new end of the string
  • Return a pointer to that.
  • One caveat: the source string must have at least one extra byte available in addition to the null terminator.

It is not as efficient as strtok_r because of the byte shuffling.

Here is an implementation:

#include <string.h>

char *tokeniz(char *str) {
    size_t n1 = strspn(str, " \f\t\r\n");
    size_t n2 = strcspn(str + n1, " \f\t\r\n");
    size_t n3 = strlen(str + n1 + n2) + 1;
    if (n2 == 0)
        return NULL;
    char token[n2];
    memcpy(token, str + n1, n2);
    memmove(str, str + n1 + n2, n3);
    char *res = str + n3;
    memcpy(res, token, n2);
    res[n2] = '\0';
    return res;
}

推荐阅读