1

I have to separate every word from a string and each word has to be put in a row in a matrix. A word is separated by spaces, tabs, newlines then the program prints each line. The end of the matrix is marked by 0.

#include<stdio.h>
#include<stdlib.h>

char    *ft_strdups(char *str, int start, int to)
{
    char *p;
    int i;

    i = 0;
    if (to < start)
        return (NULL);

    p = (char*) malloc(sizeof(char)*(to - start + 1));
    if (!p)
        return (NULL);

    while(start < to && str[start])
    {
        p[i] = str[start];
        start++;
        i++;
    }
    p[i] = '\0';
    return (p); // This function dynamicaly allocates the string
}

int     tw(char *str)
{
    int i;
    i = 0;
    while (str[i] != '\t' && str[i] != '\n' && str[i] != ' ' && str[i])
        i++;
    return (i); // This function traverses the word and returns the length
}

int     nb_words(char *str) // counts the numbers of words
{
    int i;
    int k;
    k = 0;
    while (str[i] != '\0')
    {
        if(str[i] != '\t' && str[i] != '\n' && str[i] != ' ' && str[i])
        {
            i = i + tw(str + i);
            k++;
        }
        else
            i++;
    }
    return (k);
}

char    **ft_split_whitespaces(char *str)
{
    int     i;
    char    **p;
    int     j;
    j = 0;
    i = 0;
    p = (char**)malloc(sizeof(char) * (nb_words(str) + 1));
    while(str[i] != '\0')
    {
        if (str[i] != '\n' && str[i] != '\t' && str[i] != ' ')
        {
            p[j] = ft_strdups(str, i, i + tw(str + i));;
            j++; // here is the allocation
            i = tw(str + i) + i;
        }
        else
            i++;
    }
    p[j] = 0;
    return (p);
}

int     main(int ac, char **av)
{
    char **p;
    int i;
    i = 0;
    if(ac != 2)
        return(0);
    p = ft_split_whitespaces(av[1]);
    while (p[i])
    {   
        printf("%s\n",p[i]);
        i++;
    }
}

The problem is that if i give a string that has more than 16 words (ex: ./a.out "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20") it crashes causing the printing of some non ascii characters instead of my previous words.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
JohnnyOnPc
  • 386
  • 1
  • 5
  • 18
  • If you format your code, maybe you can understand it. I won't even start analyzing your issue because of that.. – Thomas Weller Aug 19 '17 at 20:28
  • 5
    1) `sizeof(char) * (nb_words(str) + 1)` --> `sizeof(char*) * (nb_words(str) + 1)` ? – BLUEPIXY Aug 19 '17 at 20:28
  • 1
    Use [valgrind](http://valgrind.org) or an equivalent tool to help you determine the exact problem. – Iharob Al Asimi Aug 19 '17 at 20:29
  • Also `j++; // Here's the allocation`... – Thomas Weller Aug 19 '17 at 20:31
  • 1
    Its nb_word + 1 because it has to be a zero at the last line – JohnnyOnPc Aug 19 '17 at 20:34
  • 2) at `nb_words` : `i` is uninitialized. – BLUEPIXY Aug 19 '17 at 20:36
  • when calling any of the heap allocation functions (malloc, calloc, realloc) 1) the returned type is `void*` so can be assigned to any other pointer. Casting just clutters the code, making it more difficult to understand, debug, etc. 2) the expression `sizeof(char)` is defined in the standard as 1. multiplying anything by 1 has no effect and just clutters the code. 3) always check (!=NULL) the returned value to assure the operation was successful. – user3629249 Aug 19 '17 at 20:37
  • Sorry for the bad indentation the code was long and i am tired. – JohnnyOnPc Aug 19 '17 at 20:38
  • 2
    Read carefully BLUEPIXY's comment; `sizeof(char)` and `sizeof(char*)` are dramatically different. – Stephan Lechner Aug 19 '17 at 20:40
  • The posted code is NOT long. However, there is a button/icon when posting code, it looks like `{}`. by selecting all the code, then pressing that icon, the code will (mostly) be formatted for you. – user3629249 Aug 19 '17 at 23:43
  • BTW: the posted code does not cleanly compile (it causes the compiler to output some 7 warning messages. Warning messages should be fixed, not ignored. (for `gcc`, at a minimum, when compiling, use: `-Wall -Wextra -pedantic -std=gnu11 -Wconversion` ) And if 'warning messages' don't catch your attention, then also use: `-Werror` when compiling – user3629249 Aug 19 '17 at 23:48
  • for ease of readability and understanding: 1) consistently indent the code. indent after every opening brace. unindent before every closing brace. Suggest each indent level be 4 spaces. 2) insert a blank line around code blocks (for, if, else, while, do...while, switch, case, default) not randomly. 3) insert 2 or 3 spaces between functions (be consistent). 4) follow the axiom: *only one statement per line and (at most) one variable declaration per statement.* – user3629249 Aug 20 '17 at 00:02

0 Answers0