Моя str_split
функция возвращает (или, по крайней мере, я так думаю) char**
- так что, по сути, список строк.Требуется строковый параметр, разделитель char
для разделения строки и указатель на int
для размещения количества обнаруженных строк.
Способ, которым я это сделал, что может быть крайне неэффективным, должен создать буфер x длины (x = длина строки), затем скопировать элемент строки, пока мы не достигнем разделителя, или '\0'
символа.Затем он копирует буфер в char**
, который мы и возвращаем (и был malloc
отредактирован ранее, и может быть освобожден из main()
), затем очищает буфер и повторяется.
Хотя алгоритм может быть ненадежным, логика определенно правильная, поскольку мой отладочный код (_D) показывает, что он копируется правильно.Часть, на которой я застрял, это когда я делаю char**
в main
, устанавливаю его равным моей функции.Он не возвращает ноль, не вызывает сбой программы и не выдает никаких ошибок, но, похоже, тоже не работает.Я предполагаю, что это то, что подразумевается под термином «неопределенное поведение».
Во всяком случае, после долгих размышлений (я новичок во всем этом) я попробовал что-то еще, что вы увидите в коде, в настоящее время закомментированном.Когда я использую malloc, чтобы скопировать буфер в новую строку и передать эту копию вышеупомянутому символу **, он, кажется, работает отлично.ОДНАКО, это создает очевидную утечку памяти, так как я не могу освободить ее позже ... так что я потерялся.
Когда я провел какое-то исследование, я обнаружил этот пост , который почти точно соответствует идее моего кода и работает, то есть нет никакой внутренней проблемы с форматом (возвращаемое значение, параметрыи т.д.) моей функции str_split.Но у него только 1 malloc для символа **, и он работает просто отлично.
Ниже приведен мой код.Я пытался понять это, и это затягивает мой мозг, поэтому я очень ценю помощь !!Заранее извините за 'i', 'b', 'c', это немного запутанно, я знаю.
Edit : следует упомянуть об этом с помощью следующего кода,
ret[c] = buffer;
printf("Content of ret[%i] = \"%s\" \n", c, ret[c]);
это действительно печатает правильно.Только когда я вызываю функцию из main, она становится странной.Я предполагаю, что это потому, что это выходит за рамки?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define DEBUG
#ifdef DEBUG
#define _D if (1)
#else
#define _D if (0)
#endif
char **str_split(char[], char, int*);
int count_char(char[], char);
int main(void) {
int num_strings = 0;
char **result = str_split("Helo_World_poopy_pants", '_', &num_strings);
if (result == NULL) {
printf("result is NULL\n");
return 0;
}
if (num_strings > 0) {
for (int i = 0; i < num_strings; i++) {
printf("\"%s\" \n", result[i]);
}
}
free(result);
return 0;
}
char **str_split(char string[], char delim, int *num_strings) {
int num_delim = count_char(string, delim);
*num_strings = num_delim + 1;
if (*num_strings < 2) {
return NULL;
}
//return value
char **ret = malloc((*num_strings) * sizeof(char*));
if (ret == NULL) {
_D printf("ret is null.\n");
return NULL;
}
int slen = strlen(string);
char buffer[slen];
/* b is the buffer index, c is the index for **ret */
int b = 0, c = 0;
for (int i = 0; i < slen + 1; i++) {
char cur = string[i];
if (cur == delim || cur == '\0') {
_D printf("Copying content of buffer to ret[%i]\n", c);
//char *tmp = malloc(sizeof(char) * slen + 1);
//strcpy(tmp, buffer);
//ret[c] = tmp;
ret[c] = buffer;
_D printf("Content of ret[%i] = \"%s\" \n", c, ret[c]);
//free(tmp);
c++;
b = 0;
continue;
}
//otherwise
_D printf("{%i} Copying char[%c] to index [%i] of buffer\n", c, cur, b);
buffer[b] = cur;
buffer[b+1] = '\0'; /* extend the null char */
b++;
_D printf("Buffer is now equal to: \"%s\"\n", buffer);
}
return ret;
}
int count_char(char base[], char c) {
int count = 0;
int i = 0;
while (base[i] != '\0') {
if (base[i++] == c) {
count++;
}
}
_D printf("Found %i occurence(s) of '%c'\n", count, c);
return count;
}