尝试实施strtok
。
#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字符数组中推送值的方法是什么?
为什么我在那边遇到段故障?出路是什么?
答案 0 :(得分:2)
after_tokenization[j][0] = hold_chars_of_one_group;
即使您为after_tokenization
分配了足够的内存。 after_tokenization[j]
处的指针未初始化。它包含一个未指定的地址。因此,当您通过应用下标运算符[0]
取消引用它时,它就是不可取的行为。
这很可能是导致车祸的原因。
答案 1 :(得分:2)
你需要一个指针数组来保存字符串,所以它应该是:
char** after_tokenization = (char**) malloc (sizeof(char*) * 1000);
和after_tokenization[j][0]
没有意义,因为after_tokenization[j]
只是一个指针,你没有为它分配内存。这是根据您的代码修改后的版本。
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 :(得分:1)
我相信他们的代码有些问题:
malloc()
的回复。他们在C中不需要这样做。请阅读this。 after_tokenization
的分配错误。您需要为char *
指针分配空间,而不是char
个字符。它需要像这样分配:
char** after_tokenization = malloc (sizeof(char*) * 1000);
需要检查malloc()
的返回,因为它可以返回NULL
。
这一行:
after_tokenization[j][0] = hold_chars_of_one_group;
很危险,因为您并没有真正将hold_chars_of_one_group
复制到阵列中。你需要malloc()
一些空间,然后strcpy()
进入数组。他们有多种方法。
您当前的代码只会覆盖添加的先前指针的地址。它们也不需要[j][0]
,因为您只需要复制到指针位置[j]
。
strtok()
可以使用多个分隔符,但您的代码只处理1
。这不是一个真正的问题,只需考虑一下。
my_strtok()
返回char *
,但您在此函数中返回char **
。您需要将其更改为char **my_strtok()
。
您还需要free()
最后分配的内存。
这些要点有助于改进您的代码并使其正常运行。
#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;
}
注意:这只是我编写的一些代码,可以大大改进。它只是表明了这个想法。
答案 3 :(得分:0)
像这样修复
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char** my_strtok (char* arg_string, const char* arg_delimeter){
size_t len = strlen(arg_string);
char **after_tokenization = malloc(sizeof(char*) * ((len + 1)/2 +1));//max token + 1 (+1 for NULL)
char *hold_chars_of_one_group = malloc(len + 1);
int i, j, k;
i = j = k = 0;
while (*arg_string){
if (*arg_string != *arg_delimeter){
hold_chars_of_one_group[k++] = *arg_string;
} else {
hold_chars_of_one_group[k++] = 0;
after_tokenization[j++] = &hold_chars_of_one_group[i];
i = k;
}
++arg_string;
}
hold_chars_of_one_group[k] = 0;
after_tokenization[j++] = &hold_chars_of_one_group[i];
after_tokenization[j] = NULL;//NULL is terminator
return after_tokenization;
}
int main(void){
char **p = my_strtok ("anisha,kaul,shizuka,sharma", ",");
for(char **temp = p; *temp; ++temp){
printf ("-%s-\n", *temp);
}
free(*p);
free(p);
return 0;
}