Title: My program can't seem to separate words at certain cases
Tags: c;string;pointers;char;double-pointer
Question: 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&gt;
#include<stdlib.h&gt;
#include <string.h&gt;
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 = &amp;str[i];
argv[k] = st;
k++;
while (str[i] != ' ' &amp;&amp; str[i] != '\0' &amp;&amp; i < len)
{
i++;
}
str[i] = '\0';
}
i++;
return argv;
int main()
char argument[100];
scanf("%[^\n]s", &amp;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);
Comment: the posted code does not compile!  When compiling, always enable the warnings, then fix the warnings.  (for `gcc`, at a minimum use: `-Wall -Wextra -Wconversion -pedantic -std=gnu17` )  Note: other compilers have different options to obtain the same thing

Comment: where is the function: `add()`?  it is not listed in the source code nor in any of the included header files

Comment: in C, when calling any of the heap allocation functions: `malloc` `calloc` `realloc`  1) the returned type is `void*` which can be assigned to any pointer.  Casting just clutters the code, making it more difficult to understand, debug, etc..  2) always check (!=NULL) the returned value to assure the operation was successful

Comment: regarding: `scanf("%[^\n]s", &argument);`  The input format specifier used in this statement will stop inputting when it encounters a '\n' so the next character in `stdin` will NEVER be `s`.  Suggest removing the trailing `s`

Comment: when calling any of the `scanf()` family of functions, 1) always check the returned value (not the parameter values) to assure the operation was successful.  2) when using the input format specifiers '%s' and/or '%[...]', always include a MAX characters modifier that is 1 less than the length of the input buffer.  Because those specifiers always append a NUL byte to the input.  This avoids any possibility of a buffer overflow (and the resulting undefined behavior)

Comment: the posted code fails to pass the allocated memory to `free()` before exiting.  The OS (probably) will clean up this mess when the program exits  However, there are LOTS of reasons to not depend on the OS to cleanup sloppy code.

Comment: you might want to look at the function: `strtok()` for breaking the string into words.  There is no guarantee that the string, entered by the user, does not contain alphabetic characters nor other punctuation marks besides ' '.  Suggest performing a positive check for a digit rather than a negative check for a space

Comment: regarding: `while (str[i] != ' ' && str[i] != '\0' && i < len)`  the last two expressions are both (effectively) checking for the same thing.  You could simplify the code by eliminating one of those expressions

Comment: Also, you have a mem leak in `main()`. You argv = malloc(...);` but then you re-assign `argv` in the next line.

Comment: `char **argv = (char **)malloc(args);` Doesn't allocate the correct amount of mem. Should be: `char **argv = malloc(args * sizeof(char *));` –

Comment: Check this [link](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) for why you should not cast the result of malloc

Here is the accepted answer: 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 = &amp;str[i];
argv[k] = st;
k++;
while (str[i] != ' ' &amp;&amp; str[i] != '\0' &amp;&amp; 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.
Comment for this answer: I am not convinced that `scanf("%[^\n]s", &argument);` is correct, please see earlier comments. Perhaps `scanf("%[^\n]", argument);`
Comment for this answer: Please notice the `&` is removed too, although it was not commented previously. The array passed decays to a pointer.
Comment for this answer: @WeatherVane Yes you are correct, there is no need of `s`. Updated the answer.


{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 11, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2018:00:08/30/18', 'FavoriteCount': 1.0, 'PostTypeId': 1, 'Tags': '<c><string><pointers><char><double-pointer>', 'Title': "My program can't seem to separate words at certain cases", 'ViewCount': 52, 'id': 52102699, 'user_AboutMe': '', 'user_AccountId': 12694947.0, 'user_DisplayName': 'Sunil Bhagat', 'user_Reputation': 99.0, 'user_Views': 15.0, 'user_id': 9223690.0}}