I am trying to create a ft_split
function which should:
Allocates with malloc and returns an array of strings obtained by splitting ’s’ using the character ’c’ as a delimiter. The array must end with a NULL pointer.
I have included all the code with the code sample below and the breakpoint where the debugger is giving me one of the errors.
now am having problems with:
- when I input a string and at the end of it i add the delimiter it gives this error
the string:
" To be or not to be that is the question "
the error:
Segmentation fault
- when I input this string
the string:
"Hello there"
it will give the right answer and then this error
Hello
there
Segmentation fault
- i just cant figure out how i should free the memory allocations created i have included what i think was the correct way commented.
my code:
size_t ft_strlen(const char *s)
{
size_t i;
i = 0;
while (s[i] != '\0')
{
i ;
}
return (i);
}
char *ft_strcpy(char *dest, const char *src)
{
int i;
i = 0;
while (src[i] != '\0')
{
dest[i] = src[i];
i ;
}
dest[i] = '\0';
return (dest);
}
char *string_length(char const *str, char c, int i)
{
int j;
char *string;
j = 0;
// when i try the debugger with the first string in the main function it goes
// directly to this line and break.
string = (char *)malloc((ft_strlen(str)) * sizeof(*string));
if(!string)
return (NULL);
while (str[i] == c)
i ;
while (str[i])
{
*string = str[i];
if (str[i 1] == c || str[i 1] == '\0')
{
string ;
j ;
*string = '\0';
return (string - j);
}
string ;
j ;
i ;
}
return (0);
}
int count_strings(char const *str, char c)
{
int i;
int count;
int def;
i = 0;
count = 0;
def = 1;
while (str[i] == c)
i ;
while (str[i])
{
if (str[i] == c && def == 1)
{
i ;
def = 0;
}
if (str[i] != c && def == 0)
{
count ;
def = 1;
}
i ;
}
return (count);
}
int first_del(char const *str, char c, int i)
{
while (str[i] == c)
i ;
return (i);
}
char **ft_split(char const *s, char c)
{
int count;
int i;
int len;
int num_of_strings;
char **split;
char *string;
char **it;
i = 0;
count = 0;
num_of_strings = count_strings(s, c);
split = (char **)malloc((num_of_strings 1) * sizeof(char *));
if (!split)
return (NULL);
split[num_of_strings 1] = NULL;
while (i <= num_of_strings)
{
count = first_del(s, c, count);
string = string_length(s, c, count);
len = ft_strlen(string);
split[i] = (char *)malloc(len 1);
ft_strcpy(split[i], string);
count = len;
i ;
free(string);
string = NULL;
}
return (split);
}
int main(void)
{
char s[] = " To be or not to be that is the question ";
char **split_strings = ft_split(s, ' ');
for (int i = 0; i < 10; i )
printf("%s\n", split_strings[i]);
char s2[] = "Hello there";
char **split_strings2 = ft_split(s2, ' ');
for (int i = 0; i < 2; i )
printf("%s\n", split_strings2[i]);
}
CodePudding user response:
string = (char *)malloc((ft_strlen(str) 1) * sizeof(*string));
split = (char **)malloc((num_of_strings 2) * sizeof(char *));
to free the memory allocation in the main function:
int i = 0;
while (split_strings && split_strings[i])
{
free (split_strings[i]);
i ;
}
free (split_strings);
credits to xing
CodePudding user response:
First, define a function that splits a given string into multiple tokens, separated by a given separator:
bool split(const char *str, const char sep, char **tokens, const size_t maxtokens, size_t *ntokens)
{
*ntokens = 0;
const char *start = str;
const char *p = str;
for (;;) {
if (*ntokens >= maxtokens) return false;
while (*p && *p == sep) p;
if (!*p) return true;
start = p;
while (*p && *p != sep) p;
size_t len = p - start;
char *tmp = malloc(sizeof(char) * (len 1));
strncpy(tmp, start, len);
tmp[len] = '\0';
tokens[(*ntokens) ] = tmp;
if (!*p) return true;
}
return true;
}
str
is the string to be splitted;sep
is the separator/delimiter;tokens
is the array that will hold your tokens;maxtokens
is the maximum number of tokens your array can hold (i.e. its capacity);ntokens
is the actual number of tokens instr
.
Returns:
true
if the string has been tokenized totally,false
if the maximum number of tokens limit (maxtokens
) is reached and the end of string is not reached.
Then, define a function that computes the number of tokens in a given string:
size_t count_tokens(const char *str, const char sep)
{
size_t counter = 0;
for (const char *p = str; ; ) {
while (*p && *p == sep) p;
if (!*p) return counter;
while (*p && *p != sep) p;
counter;
if (!*p) return counter;
}
return counter;
}
Putting the two together:
int main(void)
{
const char *str = " To be or not to be that is the question ";
const size_t maxtokens = count_tokens(str, ' ');
size_t ntokens = 0;
char *tokens[maxtokens 1]; // 1 for the last NULL entry.
split(str, ' ', tokens, maxtokens, &ntokens);
tokens[maxtokens] = NULL; // Last entry is NULL
for (size_t i = 0; tokens[i]; i) {
printf("%d)\t%s\n", i 1, tokens[i]);
}
}
Output:
1) To
2) be
3) or
4) not
5) to
6) be
7) that
8) is
9) the
10) question
Notes:
- If you are not allowed to use
<string.h>
, you can replacestrncpy()
with your own version. - Don't forget to free the memory allocated with
malloc()
as soon as you are done with the tokens.