首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何填充C的2D字符数组中的字符串?

如何填充C的2D字符数组中的字符串?
EN

Stack Overflow用户
提问于 2017-01-22 06:37:20
回答 4查看 1.2K关注 0票数 1

试图实现strtok

代码语言:javascript
复制
#include <stdio.h>

char* my_strtok (char* arg_string, const char* arg_delimeter)
{
    char** after_tokenization      = (char**) malloc (sizeof(char) * 1000);
    char*  hold_chars_of_one_group = (char*) malloc (sizeof(char) * strlen(arg_string));

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

    while (arg_string[i])
    {
        if (arg_string[i] != *arg_delimeter)
        {
            hold_chars_of_one_group[k] = arg_string[i];
            k++;
        }
        else
        {
            after_tokenization[j][0] = hold_chars_of_one_group;

            j++;
            k = 0;
        }
        i++;
    }

    return after_tokenization;
}


int main(void)
{
    char*p = my_strtok ("qwerty,asdf,shizuka,sharma", ",");
    return 0;
}

通过放置printfs,我可以看到seg错误在这一行中:

after_tokenization[j][0] = hold_chars_of_one_group;

在崩溃j的值显示为2之前,已经为这两个数组分配了足够的内存,那么如何在C的2D字符数组中推送值呢?

为什么我在那边出了故障?出路是什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-01-22 14:16:51

我相信他们是你代码中的一些问题:

  • 您正在键入malloc()的返回。他们在C中不需要那样做,请阅读this
  • after_tokenization的分配是错误的。您需要为char *指针分配空间,而不是char字符。它需要像这样分配: char** after_tokenization = malloc (sizeof(char*) * 1000);
  • 需要检查malloc()的返回,因为它可以返回NULL
  • 这一行: after_tokenizationj = hold_chars_of_one_group; 这是危险的,因为您并没有真正地将hold_chars_of_one_group复制到数组中。为此您需要malloc()一些空间,然后将其放入数组中。它们是用于此的多种方法。 您的当前代码刚刚覆盖了前面添加的指针的地址。它们也不需要[j][0],因为您只需要复制到指针位置[j]
  • strtok()可以使用多个分隔符,但您的代码只处理1。这不是真正的问题,只是一些需要考虑的问题。
  • my_strtok()返回char *,但在此函数中返回char **。您需要将其更改为char **my_strtok()
  • 您还需要在结束时对任何分配的内存进行free()

这些要点将有助于改进您的代码,并使其具有功能。

下面是一些示例代码:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXSTR 1000

char **mystrtok(char *arg_string, const char *arg_delimeter);

int main(void) {
    char **result = NULL;

    result = mystrtok("qwerty,asdf,shizuka,sharma", ",");

    /* printing and freeing strings */
    for (size_t i = 0; result[i] != NULL; i++) {
        printf("%s\n", result[i]);
        free(result[i]);
        result[i] = NULL;
    }

    free(result);
    result = NULL;

    return 0;
}

char **mystrtok(char *arg_string, const char *arg_delimeter) {
    char **after_tokenization = NULL;
    char *group_char = NULL;
    size_t arrsize = MAXSTR, slen, count = 0, numstr = 0, delim_flag;

    /* allocation of array, with error checking */
    after_tokenization = malloc(arrsize * sizeof * after_tokenization);
    if (!after_tokenization) {
        printf("Cannot allocate %zu spaces for pointers\n", arrsize);
        exit(EXIT_FAILURE);
    }

    slen = strlen(arg_string);

    /* allocation of buffer, with error checking */
    group_char = malloc(slen+1);
    if (!group_char) {
        printf("Cannot allocate %zu bytes for string\n", slen+1);
        exit(EXIT_FAILURE);
    }

    for (size_t ch = 0; arg_string[ch]; ch++) {
        delim_flag = 0;

        /* loop to handle multiple delimeters */
        for (size_t del = 0; arg_delimeter[del]; del++) {
            if (arg_string[ch] == arg_delimeter[del]) {
                delim_flag = 1;
            }
        }

        /* no delim found, add to buffer */
        if (!delim_flag) {
            group_char[count++] = arg_string[ch];
            group_char[count] = '\0';

        /* only add if delim found and buffer is not NULL */
        } else if (delim_flag && *group_char) {

            /* make space in array */
            after_tokenization[numstr] = malloc(slen+1);
            if (!after_tokenization[numstr]) {
                printf("Cannot allocate %zu bytes for string\n", slen+1);
                exit(EXIT_FAILURE);
            }

            /* copy buffer into array */
            strcpy(after_tokenization[numstr], group_char);

            numstr++;
            count = 0;

            /* clear buffer */
            memset(group_char, '\0', slen+1);
        }
    }

    /* for last string found */
    if (*group_char) {
        after_tokenization[numstr] = malloc(slen+1);
        if (!after_tokenization[numstr]) {
            printf("Cannot allocate %zu bytes for string\n", slen+1);
            exit(EXIT_FAILURE);
        }

        strcpy(after_tokenization[numstr], group_char);
        numstr++;
    }

    /* free buffer, not longer needed */
    free(group_char);

    /* add sentinel, just in case */
    after_tokenization[numstr] = NULL;

    /* return char** at the end */
    return after_tokenization;
}

注释:--这只是我编写的一些代码,它可以得到很大的改进。它只是展示了这个想法。

票数 1
EN

Stack Overflow用户

发布于 2017-01-22 07:24:28

代码语言:javascript
复制
after_tokenization[j][0] = hold_chars_of_one_group;

即使您为after_tokenization分配了足够的内存。指针after_tokenization[j]没有初始化。它包含一个未指定的地址。因此,当您通过应用下标运算符[0]取消它的引用时,它是不受约束的行为。

这很可能是你坠机的原因。

票数 2
EN

Stack Overflow用户

发布于 2017-01-22 08:17:39

您需要一个指针数组来保存字符串,所以应该是:

代码语言:javascript
复制
char** after_tokenization      = (char**) malloc (sizeof(char*) * 1000);

after_tokenization[j][0]没有意义,因为after_tokenization[j]只是一个指针,您还没有为它分配内存。这是根据您的代码修改的版本。

代码语言:javascript
复制
char** my_strtok (char* arg_string, const char* arg_delimeter)
{
    char** after_tokenization      = (char**) malloc (sizeof(char*) * 1000);
    char*  hold_chars_of_one_group = (char*) calloc(strlen(arg_string) + 1, sizeof(char)); // use calloc to fill the memory with bytes of value zero.

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

    while (arg_string[i])
    {
        if (arg_string[i] != *arg_delimeter)
        {
            hold_chars_of_one_group[k] = arg_string[i];
            k++;
        }
        else
        {
            hold_chars_of_one_group[k] = 0;
            after_tokenization[j] = hold_chars_of_one_group;
            hold_chars_of_one_group += k+1;

            j++;
            k = 0;
        }
        i++;
    }

    // last one
    if (hold_chars_of_one_group[0] != 0) {
        hold_chars_of_one_group[k] = 0;
        after_tokenization[j] = hold_chars_of_one_group;
    }

    /*for (i = 0; i < 10; i++) {
        printf("%s\n", after_tokenization[i]);
    } */


    return after_tokenization;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41788053

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档