Making my own version of strtrim in C and its working fine but I wonder why it's working if I declare 2 array of char, like this:
static int is_set(const char *set, char c)
{
char *s;
s = (char *)set;
while (*s)
{
if (*s == c)
return (1);
s ;
}
return (0);
}
static char *ft_strsub(char const *str, unsigned int start, unsigned int end)
{
char *res;
char *s;
size_t size;
int i;
size = end - start;
res = malloc(size 1);
if (!res)
return (res);
s = (char *)str start;
i = 0;
while (*s && end-- > start)
res[i ] = *s ;
res[i] = 0;
return (res);
}
char *ft_strtrim(char const *s1, char const *set)
{
char *start;
char *s;
s = (char *)s1;
while (*s && is_set(set, *s))
s ;
if (!*s)
return (s);
start = s;
while (*s)
s ;
while (is_set(set, *--s))
;
if (*s)
* s = 0;
return (ft_strsub(start, 0, s1 - s));
}
int main(void)
{
char tst[] = " xxxtripouille";
char tst2[] = " x";
char * s = ft_strtrim(tst, tst2);
printf("%s\n", s);
free(s);
return (0);
}
But not if I pass directly a string directly in param. I'm getting bus error if I do this
int main(void)
{
/*char tst[] = " xxxtripouille";
char tst2[] = " x";*/
char * s = ft_strtrim(" xxxtripouille", " x");
printf("%s\n", s);
free(s);
return (0);
}
I must have missed something in my training ^^
Thank's in advance !
EDIT:
Thank's for reply !
Thank you for your advice, I took care to write them down, I thank you again, and I also found out why it wasn't working, it's because I'm trying to close the string and as you told me: it's a read-only string;
char *ft_strtrim(char const *s1, char const *set)
{
char *start;
char *s;
s = (char *)s1;
while (*s && is_set(set, *s))
s ;
if (!*s)
return (ft_strdup(s));
start = s;
while (*s)
s ;
while (is_set(set, *--s))
;
if (*s)
s;
return (ft_strsub(start, 0, s - start));
}
CodePudding user response:
At least this statement does not make a sense
return (ft_strsub(start, 0, s1 - s));
because there can be passed a negative value s1 - s
that will be converted to a very big positive value in the function ft_strsub because the corresponding parameter has an unsigned integer type.
Pay attention to that the compiler can issue a message that you are discarding the qualifier const as for example
char *s;
s = (char *)s1;
Also the function can return a pointer that does not point to a dynamically allocated array that you are tries to free with the function free
if (!*s)
return (s);
//...
free(s);
CodePudding user response:
Here's a few lines of code you might consider to replace your is_set()
function:
static int matchAny( const char *set, char c ) {
const char *s = set;
for( ; *s && *s != c; s )
; // just searching
return *s != '\0'; // true = match found
}
Don't "cast away" const-ness unnecessarily. Exploit the "conditional" segment of the for()
loop. Return is also a conditional: "If not reaching the end of the string of 'bad' characters, then 'c' was 'matched' in that string.
If you get "trimming the front" working, perhaps a simple "reverse string" can be used to "trim the back end, too", then "reverse string" once more. Re-use code that works.
Seeing this function, it can be made even simpler:
static int matchAny( const char *set, const char c ) {
while( *set && *set != c )
set ; // just searching
return *set != '\0'; // true = match found
}
Often the best solution is to use fewer resources (like variables) but to use them wisely. Then, flaws have fewer places to hide.