Search code examples
cstringpointerschardouble-pointer

My program can't seem to separate words at certain cases


I am mostly concerned with the find and separation function. When I reused them in another program, I found that they don't always work and sometimes show segmentation fault. I tried every possible thing I could do, but nothing worked.

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

int find(char *argument)
{
    int count = 0;
    int i = 0;
    int state = 0;
    while (argument[i] != '\0')
    {
        if (argument[i] == ' ' || argument[i + 1] == '\0')
        {
            state = 0;
        }
        else if (state == 0)
        {

            state = 1;
            count++;
        }
        i++;
    }
    return count;
}

char **sepration(int args, char str[])
{
    int i = 0;
    char **argv = (char **)malloc(args);

    int k = 0;
    int len = strlen(str);
    while (i < len)
    {

        if (str[i] != ' ')
        {
            char *st = &str[i];
            argv[k] = st;
            k++;
            while (str[i] != ' ' && str[i] != '\0' && i < len)
            {
                i++;
            }
            str[i] = '\0';
        }
        i++;
    }

    return argv;
}

int main()
{
    char argument[100];
    scanf("%[^\n]s", &argument);
    //finds the no of words in the given argument
    int args = find(argument);
    char **argv = (char **)malloc(args + 1);
    //stores the word separately in **char pointer array
    argv = sepration(args, argument);
    //adds the arguments whichs are numbers
    add(args, argv);
}

Solution

  • The problem with your solution is that you are not allocating the memory properly.
    Your double pointer argv should work as an array of strings. Hence argv should have enough memory allocated for the same. Then next question is how to allocate sufficient memory for the same. As argv should hold argc number of strings hence proper memory allocation will be
    char **argv = malloc(args * sizeof(char *)); or,
    char *argv[argc];

    Modified code will look like

    char **sepration(int args, char str[])
    {
        int i = 0;
        char **argv = malloc(args * sizeof(char *));
    
        int k = 0;
        int len = strlen(str);
        while (i < len)
        {
            if (str[i] != ' ')
            {
                char *st = &str[i];
                argv[k] = st;
                k++;
                while (str[i] != ' ' && str[i] != '\0' && i < len)
                {
                    i++;
                }
                str[i] = '\0';
            }
            i++;
        }
        return argv;
    }
    
    int main()
    {
        char argument[100];
        scanf("%[^\n]", argument);
        //finds the no of words in the given argument
        int args = find(argument);
        char **argv = malloc(args * sizeof(char *));
        //stores the word separately in **char pointer array
        argv = sepration(args, argument);
        for(int i = 0; i < args; i++)
            printf("%s\n", argv[i]);
    }
    

    Instead of char **argv = malloc(args * sizeof(char *)); you can use char *argv[argc]; as well. This will also give the same result.