C:将一个字符串拆分为两个字符串,并返回一个2元素数组

时间:2018-10-01 21:45:22

标签: c pointers c-strings strtok

我正在尝试编写一种方法,该方法采用一个字符串,并根据定界符字符串将其分为两个字符串,类似于Java中的.split:

char * split(char *tosplit, char *culprit) { 

    char *couple[2] = {"", ""};

    int i = 0; 

    // Returns first token  
    char *token = strtok(tosplit, culprit);    


    while (token != NULL && i < 2) { 
        couple[i++] = token; 
        token = strtok(NULL, culprit); 
    } 

    return couple;
} 

但我一直收到警告:

In function ‘split’:
warning: return from incompatible pointer type [-Wincompatible-pointer-types]
     return couple;
            ^~~~~~
warning: function returns address of local variable [-Wreturn-local-addr]

...当然,该方法不符合我的期望。

我在做什么错?

编辑:除了使用strtok()之外,我还愿意接受其他方法。

4 个答案:

答案 0 :(得分:2)

查看事物:

首先,您要返回一个指向(一个)字符的指针,即一个char *,而不是一个指向一个(一个)char指针的指针。因此,返回类型应为char **

第二,您返回一个局部变量的地址,该地址在函数完成后会超出范围,以后不能再访问。

第三,您定义了一个由2个指针组成的数组,而您的while循环可能超出了这些限制。

如果您确实想要拆分为两个字符串,则可以使用以下方法:

char ** split(char *tosplit, char *culprit) {     
    static char *couple[2];
    if ((couple[0] = strtok(tosplit, culprit)) != NULL) {
        couple[1] = strtok(NULL, culprit);
    }
    return couple;
} 

答案 1 :(得分:1)

我警告您使用strtok,它可能无法实现您想要的功能。如果您认为它可以执行Java拆分等操作,请阅读手册页,然后再次重新阅读七次。它实际上是根据delim中的任何值对字符串进行标记。

我认为您正在寻找这样的东西:

class UserProfile: Mappable {

    var username: String?
    var signature: String?

    required init?() {}
    required init?(map: Map) {}

    func mapping(map: Map) {
        username   <- map ["username"]
        signature  <- map ["signature"]
    }

}

哪个打印出“蓬松的兔子!”。

答案 2 :(得分:0)

首先strtok修改tosplit的内存,因此请确保这就是您要执行的操作。如果是这样,请考虑以下问题:

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

/* 
 * NOTE: unsafe (and leaky) implementation using strtok
 *
 * *into must point to a memory space where tokens can be stored
 * or if *into is NULL then it allocates enough space.
 * Returns:
 *  allocated array of items that you must free yourself
 *
 */


char **__split(char *src, const char *delim)
{
    size_t idx = 0;
    char *next;
    char **dest = NULL;


    do {
        dest = realloc(dest, (idx + 1)* sizeof(char *));
        next = strtok(idx > 0 ? NULL:strdup(src), delim);
        dest[idx++] = next;
    } while(next);


    return dest; 
}


int main() {
    int x = 0;
    char **here = NULL;
    here = __split("hello,there,how,,are,you?", ",");

    while(here[x]) {
        printf("here: %s\n", here[x]);
        x++;
    }

}

您可以实现一个更安全且无泄漏的版本(请注意strdup),但希望这是一个好的开始。

答案 3 :(得分:-1)

couple的类型为char**,但是您已将函数返回类型定义为char*。此外,您正在将指针返回到局部变量。您需要将指针数组从调用方传递到函数中。例如:

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

char** split( char** couple, char* tosplit, char* culprit ) 
{ 
    int i = 0; 

    // Returns first token  
    char *token = strtok( tosplit, culprit);    

    for( int i = 0; token != NULL && i < 2; i++ ) 
    { 
        couple[i] = token; 
        token = strtok(NULL, culprit); 
    } 

    return couple;
} 

int main()
{
    char* couple[2] = {"", ""};
    char tosplit[] = "Hello World" ;

    char** strings = split( couple, tosplit, " " ) ;

    printf( "%s, %s", strings[0], strings[1] ) ;

    return 0;
}