如何在C中存储给定分隔符的子字符串

问题描述

假设我有一系列这种形式的数据:

"SomethingIDontCareAbout : SomethingICareAbout"

“:”之后的部分的长度当然可以变化。

这里的目标只是有效地存储“SomethingICareAbout”子字符串。我做了这个函数,但问题是我存储了两个子字符串,所以这似乎是在浪费内存。是否有助于降低时间/空间复杂度?

char** ExtractKey(char* S)           
{
    int n = strlen(S);
    int count = 0,i = 0,j = 0;
    for(i = 0; i < n; i++)
    {
        if(S[i] == ':')
            break;
        
        count++;
    }
    char** T = (char**)malloc(2 * sizeof(char*));

    T[0] = (char*)malloc((count + 1)  * sizeof(char));
    T[1] = (char*)malloc((n - count) * sizeof(char));

    for(i = 0; i < count; i++)                          // inefficient ? cus we won't need T[0] [j]
    {
        T[0][j] = S[i];
        j++;
    }
    T[0][j+1] = '\0';
    j = 0;
    for(i = count + 1; i < n; i++)
    {
        T[1][j] = S[i];
        j++;
    }
    T[1][j+1] = '\0';
    return T;
}

解决方法

老实说,如果使用 strtok() 来分割这些字符串,这可以有效地完成。我设计了以下代码,用于解析二维数组的每个字符串,并使用此处为 : 的公共分隔符。

现在,让我们看一下代码(注意注释):

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

#define MAX_LEN 128

int main(void) {
    // The 2-D string
    char str[][MAX_LEN] = {"SomethingElse : SomethingToCareAbout","Something2 : SomethingToCare2","Unnecessary : Necessary"};
    int size = sizeof(str) / sizeof(str[0]);

    // Applying Variable-Length Array (valid in C)
    char store_cared_ones[size][MAX_LEN];

    for (int i = 0; i < size; i++) {
        // Declaring a temporary pointer variable to obtain the required
        // substring from each string
        char *sub_str = NULL;
        sub_str = strtok(str[i],": ");
        sub_str = strtok(NULL,": ");

        // Copying the 'sub_str' into each array element of 'store_cared_ones'
        strcpy(store_cared_ones[i],sub_str);
    }

    // Displaying each of 'store_cared_ones'
    for (int i = 0; i < size; i++)
        fprintf(stdout,"%s\n",store_cared_ones[i]);

    return 0;
}

最后,让我们看看这段代码做了什么:

rohanbari@genesis:~/stack$ ./a.out
SomethingToCareAbout
SomethingToCare2
Necessary
,

没有理由发明搜索字符串中的字符或字符串的副本。

如果输入数据的寿命足以让您使用“值”部分,只需返回一个指向该值的指针:

char* ExtractKey(char* S)           
{
  return strchr(S,':');
}

如果没有,或者您出于某种原因需要单独的副本:

char* ExtractKey(char* S)           
{
  return strdup(strchr(S,':'));
}