有没有一种方法可以将字符串数组拆分为令牌上的字符串子数组

时间:2019-06-09 07:45:48

标签: c arrays string split

基本上,有什么方法可以将字符串数组拆分为C中标记("|")前后的字符串数组。

下面显示一个示例。

char *input[] = {"hello","I","am","|","a","cool","|","guy"}

//code

结果为3个数组,包含

{"Hello","I","am"}
{"a","cool"}
{"guy"}

我尝试了strtok,但这似乎将一个字符串分成多个部分,而不是将一个字符串数组分解为新的,单独的子字符串数组。我也不完全知道将存在多少个"|"令牌,并且将需要未知数量的新数组(可以说少于10个)。它们将被传递到execvp,因此将其作为一个字符串并仅记住在哪里开始和停止查找是行不通的。

3 个答案:

答案 0 :(得分:1)

  

它们将被传递给execvp

假设字符串包括要执行的程序(execvp()的第一个参数),并且按照该指针数组的出现顺序使用字符串

char *input[] = {"hello","I","am","|","a","cool","|","guy"}

那么一个可能没有任何重复的简单解决方案可能看起来像这样:

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

char * input[] = {"hello", "I", "am", "|", 
                  "a", "cool", "|",
                  "guy", "|"}; /* note the additional trailing `"|"`. */

int main(void)
{
  char ** pcurrent = input;
  char ** pend = pcurrent + sizeof input / sizeof *input;

  while (pcurrent < pend)
  {
    {
      char ** ptmp = pcurrent;
      while (ptmp < pend && **ptmp != '|')
      {
        ++ptmp;
      }

      *ptmp = NULL;
    }

    {
      pid_t pid = fork();
      if ((pid_t) -1) == pid)
      {
        perror("fork() failed");
        exit(EXIT_FAILURE);
      }

      if ((pid_t) 0) == pid) /* child */
      {
        execvp(pcurrent[0], pcurrent);
        perror("execvp() failed");
        exit(EXIT_FAILURE);
      }

      /* parent */
      pcurrent = ptmp + 1;
    }
  }  /* while (pcurrent < pend) */
}  /* int main(void) */

答案 1 :(得分:0)

您需要手动拆分输入数组。并动态分配一个新的位置来存储结果。例如。为:

#include <stdio.h>
#include <stdbool.h>

int main()
{
    char *input[] = {"hello","I","am","|","a","cool","|","guy"};

    int inputLength = sizeof(input)/sizeof(input[0]);
    printf("inputLength - %d\n", inputLength);
    const char ***result2DimArray = malloc(sizeof(char**) * inputLength);
    int *result2DimArrayLengths = malloc(sizeof(int) * inputLength);
    memset(result2DimArrayLengths, 0, sizeof(int) * inputLength);

    const char **currentSection = 0;
    int nextSectionNumber = 0;
    for(int inputIndex = 0; inputIndex < inputLength; inputIndex++)
    {
        if(input[inputIndex][0] == '|')
        {
            currentSection = 0;
        }
        else
        {
            if(!currentSection)
            {
                currentSection = malloc(sizeof(char*) * inputLength);
                result2DimArray[nextSectionNumber] = currentSection;
                nextSectionNumber++;
            }

            *currentSection = input[inputIndex];
            currentSection++;
            result2DimArrayLengths[nextSectionNumber-1]++;
        }
    }

    /*Checking the result*/
    printf("total sections - %d\n", nextSectionNumber);
    for(int i=0; i<nextSectionNumber;i++)
    {
        for(int j=0;j<result2DimArrayLengths[i];j++)
        {
            printf(result2DimArray[i][j]);
            printf(", ");
        }
        puts("");
    }

    return 0;
}

答案 2 :(得分:0)

这是不涉及动态内存分配的解决方案。

在进入细节之前...

我认为在解决此类问题时考虑“字符串”如何存储在内存中非常有用。它可能看起来像附件中的图片。 (内存地址是完全不现实的-每个字符串的末尾都将有空终止符-但您知道了。)

enter image description here

如图所示,每个“子阵列”所需的重要信息都可以成对存储<char **, int>char **是子数组中第一个“字符串”的地址; int是它包含的字符串数。

我们可以使用struct string_array_t来存储此信息。

typedef struct {
    // Pointer to first string in sub-array
    char **p;
    // Number of strings in sub-array
    int count;
} string_array_t;

我们在堆栈上分配这些的数组;因此,只要我们分配足够的子数组,就不需要malloc()free()

    string_array_t string_arrays[MAX_SUB_ARRAYS] = {0};
    char *input[] = {"hello", "I", "am", "|", "a", "cool", "|", "guy"};
    // Pointer to current sub-array
    string_array_t *cur = NULL;
    size_t n_sub_arrays = 1;

初始化我们的计数器和指针:

    int i = 0, j = 0, k = 0;

    cur = &string_arrays[0];
    size_t n_strings_total = sizeof(input) / sizeof(input[0]);

然后遍历数组。

    for (i = 0; i < n_strings_total; i++) {
        if (!strcmp(input[i], "|")) {
            // Store total number of strings in this sub-array
            cur->count = k;
            k = 0;
            // Switch to next sub-array
            cur = &string_arrays[++j];
            if (j >= MAX_SUB_ARRAYS) {
                fprintf(stderr, "Not enough sub-arrays allocated ...\n");
                break;
            }
            n_sub_arrays++;
            continue;
        }
        if (k == 0) {
            cur->p = &input[i];
        }
        k++;
    }
    cur->count = k;

打印结果。

    printf("Found %zu sub arrays ...\n", n_sub_arrays);
    for (i = 0; i < n_sub_arrays; i++) {
        string_array_t *cur = &string_arrays[i];
        for (j = 0; j < cur->count; j++) {
            printf("%s ", *(cur->p++));
        }
        printf("\n");
    }