使用strtok时出现意外行为

时间:2016-10-04 17:44:03

标签: c string

所以我给了一个字符串:

Hello6World66ABC

我被告知要将字符'6'的单个实例替换为两个星号"**"

多个6的实例是这些字符中的两个"^^"(连续数字6的任何组合都符合条件。

我试图通过传递char *中的每个字符来做到这一点,然后如果我找到6个字符,我检查下一个字符是否为6,否则我们有第一个案例,否则我们有第二种情况(多个6)。

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

int main(void) {
    char * str;
    int i;
    str = malloc(17);

    strcpy(str,"Hello6World66ABC");

    for(i=0; i < strlen(str); i++) {
        if(str[i] == '6') {
            if(str[i+1] != '6') {
                char * token = strtok(str,"6");
                strcpy(str,token);
                strcat(str,"**");
                printf("String is now %s\n",str);

                token = strtok(NULL,""); /*get the rest of the string*/ /* should be World66ABC */
                printf("Rest of the string is %s\n",token);
                str = (char *) realloc(str,strlen(str) + strlen(token) + 1);
                strcat(str,token);
                printf("String is now %s\n",str);
                /*    should be Hello**World66ABC    */
            }
            else {
                /*if the next characters are also (multiple ones in a row)  6's, replace it with two ^^ characters*/
                char * token = strtok(str,"6");
                token = strtok(NULL,"6");
                printf("TOKEN IS %s\n",token);

                strcpy(str,token);
                strcat(str,"^^");

                token = strtok(NULL,""); /*get the rest of the string*/ /* should be World66ABC */
                printf("Rest of the string is %s\n",token);
                str = (char *) realloc(str,strlen(str) + strlen(token) + 1);
                strcat(str,token);
                printf("String is now %s\n",str);


            }
        }
    }

    free(str);
    return 0;
}

通过给出的字符串,我期望的最终字符串应为:

Hello**World^^ABC

然而,我的strtok电话不按照我的意图工作。

在第二个if语句中,我检查if (str[i+1] != '6'),我正在检查是否只有一个6,有。

然后我打电话给strtok并在它之前打印所有内容: 它打印:Hello**

哪个是对的 我把新字符strcat到它上面,但是,在我的第二次strtok调用中,为了得到字符串的其余部分,它只是不起作用。

而是打印:

"Rest of the string is *"

很明显,即使我将分隔符设置为空字符串,它也不会获得字符串的其余部分。

我尝试将分隔符更改为其他字符,但每个字符都会产生相同的输出。我也在重新分配,因为在第一种情况下字符串变长了。 else语句似乎永远不会运行,即使我明显有一个多个6的情况。

我不确定我在哪里出错了,有什么想法吗?

2 个答案:

答案 0 :(得分:1)

这是未经测试的,但它显示了一般的想法。

strcpy(str,"Hello6World66ABC");

// New string will be at most 2x as long
char *new_str = calloc(strlen(str) * 2 + 1, 1);
int new_str_index = 0;

for (int i = 0; 0 != str[i]; i++) {
    // Check for 6
    if ('6' == str[i]) {
        // Check for 2nd 6
        if ('6' == str[i+1]) {
            // Add chars
            new_str[new_str_index++] = '^';
            new_str[new_str_index++] = '^';
            // Consume remaining 6s - double check this for off-by-one
            while ('6' == str[i+1]) i += 1;
        }
        else {
            // Add chars
            new_str[new_str_index++] = '*';
            new_str[new_str_index++] = '*';
       }
    }
    // No 6s, just append text
    else {
        new_str[new_str_index++] = str[i];
    }
}

答案 1 :(得分:1)

OP要求一种简单的方法来改变字符串中的'6'字符。如果你想写另一个字符串而不是直接打印,我会留给你定义另一个(足够大的)字符串,并将字符复制到该字符串而不是stdout。但是不要试图改变传递的字符串,注定要失败。

#include <stdio.h>

void sixer(char *str)
{
    int i = 0, sixes;
    while(str[i] != '\0') {
        if(str[i] == '6') {
            sixes  = 0;
            while(str[i] == '6') {
                sixes++;
                i++;
            }
            if(sixes == 1) {
                printf("**");
            }
            else {
                printf("^^");
            }
        }
        else {
            printf("%c", str[i]);
            i++;
        }
    }
    printf("\n");
}

int main(void)
{
    sixer("Hello6World66ABC");
    sixer("6");
    sixer("66666");
    return 0;
}

节目输出

Hello**World^^ABC
**
^^