0

I want to write a function which accepts as an argument array of characters, and the function should change the order of the words - I want the original string to be changed by the function, and not just print the sentence backwards.

Now, I wrote a program which copies the words in the opposite order to a new array of the same length, but the original array is not affected when the function is done. Here's my code:

void revSent(char* str){
    int n =strlen(str);
    int i=0, j=n-1;
    char* rev = (char*) malloc(n+1);
    while (j>0){                      //Copy the words from the last one to the first one 
        if(str[j] ==' '){
            int k = j+1;
            while(str[k] != ' ' && str[k]!='\0'){
                rev[i]=str[k];
                k++;
                i++;
            }
            rev[i] = ' ';
            i++;
        }
        j--;
    }
    if (j==0){                        //Copy the first word
        int k=j;
        while (str[k]!= ' ' && str[k]!= '\0'){
            rev[i]=str[k];
            k++;
            i++;
        }
        rev[i]='\0';
    }
    char* tmp = str;                //Make str point to rev and free the allocated space pointed by str
    str = rev;
    free(tmp);
    tmp = NULL;
}

I dont want the function to return anything - I want it to stay a void function. What went wrong here and what should I change?

Thanks in advance.

Note: Im using free(tmp) since the Im going to use as an argument for this function an array which was allocated using malloc in the main function.

Edit: here's an example of the output I dont want:

Please, enter your sentence
I dont think it will work
I dont think it will work
And the result is
I dont think it will work

Process returned 0 (0x0)   execution time : 6.141 s
Press any key to continue.

EDIT 2:

Here's example for a correct Output I want:

Please, enter your sentence
By reversed order this is what I mean
By reversed order this is what I mean
And the result is
mean I what is this order reversed By

Process returned 0 (0x0)   execution time : 7.643 s
Press any key to continue.
FreeZe
  • 123
  • 6
  • Please show a [mcve] – Jabberwocky Nov 17 '21 at 14:40
  • 1
    Note that `str = rev;` accomplishes nothing, because you're just changing the *local copy* of the pointer. You'd need to be using a double pointer to affect the caller's pointer. – Fred Larson Nov 17 '21 at 14:42
  • @FredLarson I see. So my options are to change the argument of this function to a double pointer, or simply copy rev into str using strcpy? is there efficient way to change the order of the words whithout an extra array? – FreeZe Nov 17 '21 at 14:46
  • It's simple enough to reverse a string in-place. There are [examples on Stack Overflow](https://stackoverflow.com/q/198199/10077). – Fred Larson Nov 17 '21 at 14:51
  • @FredLarson This is not what Im doing here - note that in your examples the whole sentence being reversed, while im trying to keep each word ordered and just replace the order of the words. Im sorry if I wasnt clear enough – FreeZe Nov 17 '21 at 14:58
  • Oh, right. Words would be harder to do in-place. But yes, you could `strcpy` the result back to the caller's pointer. – Fred Larson Nov 17 '21 at 14:59
  • I think you could reverse the words in place by first reversing the entire string in place and then go through the string and reverse the letters of each word in place. – nielsen Nov 17 '21 at 15:09
  • Your code would be much improved by refactoring. Write a function that copies a word from one place to another, and maybe also one that returns an array of pointers to the beginnings of the words. Trying to work at a high level (reversing words) and low level (copying characters) at the same time is usually a bad idea. – Caleb Nov 17 '21 at 15:14

1 Answers1

0

The following solution implements my comment above. First the entire string is reversed in place. This gives a string where the words are reversed, but so are the characters within each word. Then the characters in each word are reversed to get them back in order:

#include <stdio.h>
#include <string.h>

// Reverse characters in sequence of given length
void reverse(char *str, size_t len)
{
    for(size_t i = 0; i < len / 2; i++)
    {
        char tmp = str[i];
        str[i] = str[len-i-1];
        str[len-i-1] = tmp;
    }
}

// Determine length of next word
size_t wordLen(char *str)
{
    size_t len = 0;
    while(str[len] != 0 && str[len] != ' ')
    {
        len++;
    }
    return len;
}

void revSent(char *str)
{
    // Reverse all characters
    reverse(str, strlen(str));

    // Reverse characters in each word
    size_t offset = 0;
    while(str[offset] != 0)
    {
        size_t wlen = wordLen(str+offset);  // Find length of next word
        reverse(str+offset, wlen);          // Reverse characters in the word
        offset += wlen;                     // Skip to end of the word
        while(str[offset] == ' ') offset++; // Skip spaces
    }
}

int main(void)
{
    char str[] = "By reversed order this is what I mean";
    printf("%s\n", str);
    revSent(str);
    printf("%s\n", str);
}

Sample output:

By reversed order this is what I mean
mean I what is this order reversed By
nielsen
  • 5,641
  • 10
  • 27