Reputation: 89
I am trying to separate each word from a character array and put them into a pointer array, one word for each slot. Also, I am supposed to use isspace() to detect blanks. But if there is a better way, I am all ears. At the end of the code I want to print out the content of the parameter array.
Let's say the line is: "this is a sentence". What happens is that it prints out "sentence" (the last word in the line, and usually followed by some random character) 4 times (the number of words). Then I get "Segmentation fault (core dumped)".
Where am I going wrong?
int split_line(char line[120])
{
char *param[21]; // Here I want to put one word for each slot
char buffer[120]; // Word buffer
int i; // For characters in line
int j = 0; // For param words
int k = 0; // For buffer chars
for(i = 0; i < 120; i++)
{
if(line[i] == '\0')
break;
else if(!isspace(line[i]))
{
buffer[k] = line[i];
k++;
}
else if(isspace(line[i]))
{
buffer[k+1] = '\0';
param[j] = buffer; // Puts word into pointer array
j++;
k = 0;
}
else if(j == 21)
{
param[j] = NULL;
break;
}
}
i = 0;
while(param[i] != NULL)
{
printf("%s\n", param[i]);
i++;
}
return 0;
}
Upvotes: 0
Views: 2005
Reputation: 148870
There are many little problems in this code :
param[j] = buffer; k = 0;
: you rewrite at the beginning of buffer erasing previous wordsif(!isspace(line[i])) ... else if(isspace(line[i])) ... else ...
: isspace(line[i])
is either true of false, and you always use the 2 first choices and never the third.if (line[i] == '\0')
: you forget to terminate current word by a '\0'Here is a working version :
int split_line(char line[120])
{
char *param[21]; // Here I want to put one word for each slot
char buffer[120]; // Word buffer
int i; // For characters in line
int j = 0; // For param words
int k = 0; // For buffer chars
int inspace = 0;
param[j] = buffer;
for(i = 0; i < 120; i++) {
if(line[i] == '\0') {
param[j++][k] = '\0';
param[j] = NULL;
break;
}
else if(!isspace(line[i])) {
inspace = 0;
param[j][k++] = line[i];
}
else if (! inspace) {
inspace = 1;
param[j++][k] = '\0';
param[j] = &(param[j-1][k+1]);
k = 0;
if(j == 21) {
param[j] = NULL;
break;
}
}
}
i = 0;
while(param[i] != NULL)
{
printf("%s\n", param[i]);
i++;
}
return 0;
}
I only fixed the errors. I leave for you as an exercise the following improvements :
120
), you should at least have a #define
and use symbolic constants, or better accept a line of any size - here again it is not simple because you will have to malloc and free at appropriate places, and again would be a different questionAnyway good luck in learning that good old C :-)
Upvotes: 3
Reputation: 11047
This line does not seems right to me
param[j] = buffer;
because you keep assigning the same value buffer
to different param[j]
s .
I would suggest you copy all the char
s from line[120]
to buffer[120]
, then point param[j]
to location of buffer + Next_Word_Postition
.
Upvotes: 1
Reputation: 706
You may want to look at strtok
in string.h
. It sounds like this is what you are looking for, as it will separate words/tokens based on the delimiter you choose. To separate by spaces, simply use:
dest = strtok(src, " ");
Where src
is the source string and dest
is the destination for the first token on the source string. Looping through until dest == NULL
will give you all of the separated words, and all you have to do is change dest
each time based on your pointer array. It is also nice to note that passing NULL
for the src
argument will continue parsing from where strtok
left off, so after an initial strtok
outside of your loop, just use src = NULL
inside. I hope that helps. Good luck!
Upvotes: 0