A segmentation fault is usually caused when the program tries to access memory which it is not allowed to use. Read What is a segmentation fault?.
In your case it might be caused because of the way you use the character array c[]
and the strtok()
function.
strtok()
modifies its first argument based on the delimiters which are in the form of its second argument.
For example, if you do
char s[]="hello world how are you?";
strtok(s, " ");
printf("\n%s", s);
the output would be just
hello
and not
hello world how are you?
because the position with the delimiter is overwritten.This is a reason why strtok()
can't be used on string literals.
The reason why you don't get error when you try without the while
loop may be because c[]
has a few spaces in the part of memory that the program is allowed to access. strtok()
will go on looking for delimiters till the \0
denoting end of string is found which may be anywhere since c[]
has garbage.
You haven't initialised c[]
and it just has some garbage value. And there may or may not be a
(space) which the strtok()
is to consider as delimiter within the space for 1000 characters that you set aside in c[]
. And if there is no
within this 1000 bytes, the strtok()
would look beyond the bounds of the array c[]
and may modify memory which the program is not allowed to access.
Note that with
scanf("%[^\n]s",c);
you are asking the program to read everything till a \n
and then an 's'. The extra s is not necessary. Just '%[^\n]` would've done.
But scanf()
is not suited for this as it could easily lead to overflow. Read Disadvantages of scanf. You could try fgets()
instead like
if( fgets(c, sizeof(c), stdin)==NULL )
{
//something went wrong.
}
fgets()
returns NULL
upon error.
but keep in mind that fgets()
would read in the trailing \n
as well. Read Removing trailing newline character from fgets
input.
So, as suggested in that post, do something like
char *pos;
if( (pos=strchr(c, '\n'))!=NULL )
{
*pos='\0';
}
to replace the \n
with the nul character denoting the end of string.
Had you done
scanf("%[^\n]", c);
instead, the \n
would've remained unconsumed in the input buffer which could cause trouble if not taken care of later.
You may also want to check out How to convert a string to integer in C as atoi()
does not allow for proper error checking.