1

I am trying to reverse a string in C with pointers but the output is really weird. The logic seems good but I am not sure why it gets outputted like this. Here is the code:

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

int main()
{
    char str[20], reverse_str[20], *pointer;
    int i = 0;

    printf("%s", "Enter any string: ");
    scanf("%s", str);
    pointer = str;

    int string_length = strlen(pointer);

    //int count = 0;
    for (int i = string_length; i > 0; i--){
        reverse_str[i -1] = *pointer;
        pointer++;
    }
    printf("%d\n", string_length);
    printf("Original string = %s\n", str);
    printf("Reversed string = %s\n", reverse_str);

}

The output looks like this:

Enter any string: Hello

Original string = Hello
Reversed string = olleH╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠Hello
Clancinio
  • 734
  • 6
  • 21
  • 40
  • 2
    You forgot to append a null terminator to `reverse_str`. – Barmar Jan 30 '20 at 17:15
  • 2
    you forgot to NUL-terminate `reverse_str`. E.g. add `reverse_str[string_length] = '\0';` after the loop – Ingo Leonhardt Jan 30 '20 at 17:15
  • 1
    or before it, it doesn't matter when. – Barmar Jan 30 '20 at 17:16
  • 1
    You can refer this https://stackoverflow.com/questions/198199/how-do-you-reverse-a-string-in-place-in-c-or-c++ – ESCoder Jan 30 '20 at 17:18
  • 1
    It works. Thanks – Clancinio Jan 30 '20 at 17:22
  • @Barmar What do you mean with "before it, it doesn´t matter when"? The string needs to be terminated by a `\0`, not preceded by it. – RobertS supports Monica Cellio Jan 30 '20 at 17:36
  • 1
    @RobertSsupportsMonicaCellio You can assign the null terminator as Ingo suggested before the loop, it doesn't have to be after the loop. – Barmar Jan 30 '20 at 17:37
  • 1
    @Barmor Ah, before the loop; I´d thought you mean at the beginning of the respective string. lol – RobertS supports Monica Cellio Jan 30 '20 at 17:38
  • regarding: `int string_length = strlen(pointer);` The function: `strlen()` returns type `size_t` not `int`, so `string_length` should be declared as `size_t`, not `int` and everything that uses that variable should also be of type: `size_t` – user3629249 Jan 31 '20 at 06:23
  • regarding: `scanf("%s", str);` When using the 'input format conversion' specifiers `%s` and/or `%[...]` always include a MAX CHARACTERS modifier that is 1 less than the length of the input buffer because these specifiers always append a NUL byte to the input. This also avoids a buffer overflow and the resulting undefined behavior – user3629249 Jan 31 '20 at 06:26

2 Answers2

4

This is when the role of null terminator comes in which is often ignored as a silly bit of information by beginners.

In C, every string is terminated by a null character because there needs to be some way to know when a particular string ends starting from its initial location in memory. If you properly initialize the string or put in \0 appropriately then the string can be displayed as is. Otherwise every character in memory starting from the zeroth index of the string will be displayed until it encounters a null character. This is how a printf("%s", str) works, in simple words.

You get that weird output because of this reason. This explains it much better.

Solution:

Add reverse_str[string_length] = '\0'; after you reverse your string using that for loop, so that your resultant string is properly null terminated.

Bonus:

And the reason why you got a considerably sane output is that you were lucky since the compiler allocated str and reverse_str close to each other in a direction such that even if you miss the null terminator on reverse_str you hit the null terminator of str.

Ardent Coder
  • 3,777
  • 9
  • 27
  • 53
1

To print a string, the string needs a NUL-terminator \0 but reverse_str doesn´t have one.

You need to set a \0 at the end of revers_str, like:

reverse_str[string_length] = '\0';

to make it print the right output.