Solving KNKING exercise 14, chapter 8. Reverse the words

Viewed 184

I'm reading K.N.King C programming and I have an issue about it.

I'm solving project 5, chapter 12 which is modify project 14 from chapter 8 by using the pointer .

Project 8.14

Write a program that reverses the words in a sentence:

Enter a sentence: you can cage a swallow can't you?

Reversal of sentence: you can't swallow a cage can you?

Hint: Use a loop to read the characters one by one and store them in a one-dimensional char array. Have the loop stop at a period, question mark, or exclamation point (the "terminating character"), which is saved in a separate char variable. Then use a second loop to search backward through the array for the beginning of the last word. Print the last word, then search backward for the next-to-last word. Repeat until the beginning of the array is reached. Finally, print the terminating character.

#include <stdio.h>
#include <ctype.h>

#define N 100


int main()
{
    char arr[N] = {0};
    
    char *p, *q, mark = 0;
    int c;
    p = arr;
    
    while((c = getchar()) != '\n' && p < arr + N)
    {
        
        if(c == '?' || c == '.' || c == '!')
        {
            mark = c;
            break;
        }
        else
            *p++ = c;
    }
    *p = '\0';
    
    while(p >= arr)
    {
        while(*--p != ' ' && p != arr);
        q = p == arr ? arr : p + 1;
        
        while(*q != '\0' && *q != ' ')
        {
            printf("%c", *q++);
        }
        if(p >= arr)
            printf(" ");
        
    }
    printf("\b%c", mark);
    printf("\n");
}


the problem is if I enter enter a sentence "My name is jiyong!", expected output is "jiyong is name My!" but the output always has '\xxx'. How can I get rid off? and what is these '\xxx' things?

ran under Xcode 12.4

1 Answers

The second loop looks too complicated to me. You are required to scan the string backwards and print every word found, right? But you're not required to retain the whole sentence...?

So we can replace every space character with zero, thus terminating each word.

    while((c = getchar()) != '\n' && p < arr + N)
    {
    
        if(c == '?' || c == '.' || c == '!')
        {
            mark = c;
            break;
        }
        else
            *p++ = (c == ' ') ? '\0' : c;
    }
    *p = '\0';

Then we can seek words backwards and print them as strings instead of iterating over their characters:

    while(--p > arr)    // all words except the first one
    {
        if(!*p && p[1]) //p[1] or *(p + 1)
            printf("%s ", p+1);
    }

    printf("%s", arr);  // the first word goes last
    if(mark)
        printf("%c", mark);

    printf("\n");

I assumed p gets incremented at least once in the first loop, that is the input line is never empty. But that seems a valid assumption (although not very safe) as the input is defined as 'a sentence', so it should not be empty...

Related