1

My assignment is to write a function that takes an input string from a user, tokenize it into several strings each containing an individual word from the input sentence, and then reverses the sentence. The result will be the sentence input but with the words in the reverse order.

For now, I just have the function taking in the input, tokenizing it into individual words, storing those words into an array, and printing out each individual word in order. I do not have the process for reversing the order of the words written yet.

Here is the code for the function i have handling this so far:

void reverse(void){
printf("\n\n%s\n", "Reverse words in String: ");

char input[200];
printf("\n%s", "Enter string\n> ");
scanf("%s", &input);

char reverseSentence[200];
char sentenceParts[20][200];
int wordCount = 0;

char *thisWord = strtok(input, " ");
strcpy(sentenceParts[wordCount], thisWord);
wordCount++;


while(thisWord != NULL){
    thisWord  = strtok(NULL, " ");
    strcpy(sentenceParts[wordCount], thisWord);
    wordCount++;
}

printf("\n\n");

for(int i = 0; i < wordCount + 1; ++i){
    printf("%s%s", sentenceParts[i], " ");
}
}

The problem lies in the while statement:

while(thisWord != NULL){
    thisWord  = strtok(NULL, " ");
    strcpy(sentenceParts[wordCount], thisWord);
    wordCount++;
}

The program exits with a segmentation fault error at the strcpy statement. I cannot understand for the life of me why it is doing this. It seems like it worked just fine outside of the while loop.

Any thoughts? I've been stuck on this for quite a bit now and can't find too many other resources out there to help.

1 Answers1

1

Updating thisWord with the next token should happen at the end of the loop body. As is, you'll eventually update thisWord with a NULL, and then call strcpy with a NULL. And that is your segfault.

So the loop should look like this:

char *thisWord = strtok(input, " ");
while(thisWord != NULL){
    strcpy(sentenceParts[wordCount], thisWord);
    wordCount++;
    thisWord  = strtok(NULL, " ");
}

The other problem (pointed out by @WhozCraig in the comments) is that you are inputting the line using scanf("%s", ...). That doesn't work because scanf will stop at the first whitespace character. Hence, you'll only get one word at a time from scanf. To get an entire line, use the fgets function.

user3386109
  • 34,287
  • 7
  • 49
  • 68
  • Would this occur even on the first pass through the loop? I ran this through a debugger and it seemed to happen immediately upon the first pass, which makes this answer seem strange. – Matt Angelucci Oct 15 '18 at 04:55
  • @MattAngelucci It could potentially if there is exactly one word on a particular line. In the code in the question, you call `strtok` once outside the loop. So the first call to `strtok` inside the loop will return `NULL` if there is only one word. – user3386109 Oct 15 '18 at 04:55
  • Thank you, that seemed to have eliminated the segmentation fault. It turns out that thisWord is indeed NULL after the first passthrough. I am attempting now to figure out why that is. The behavior you describe as if the input was only one word is occuring even when i input multiple. Every test string I input is 3 or 4 potential tokens seperated by spaces. – Matt Angelucci Oct 15 '18 at 05:07
  • 1
    @MattAngelucci You're using `scanf` with `%s` to pull the string from standard input. But `scanf` stops scanning for `%s` on encounter of white space. Therefore, using a white space delimiter is pointless. There can be at-most one because `scanf` stopped scanning (and there could be less than one, but you never check that either; that's a bug). You should use `fgets` to get a full *line* from stdin, then use that line to pull out white space separated sequences. – WhozCraig Oct 15 '18 at 05:13
  • @WhozCraig Thank you! That has cleared up all my issues so far. I will be sure to remember that, I was not aware of that aspect of scanf up until this point. – Matt Angelucci Oct 15 '18 at 05:17