Trying to reverse an array of characters

Viewed 80

Hi I'm new to C programming. I'm currently struggling with why my code isn't working. An example input would be "1234". It should output 4321, however its not outputting. Anyways, here's my code, I'm sure one of you could answer why its not working.

int task4(void) {
  printf("\nPlease enter a four digit number:\n");
  char input[4];
  char revInput[4];
  scanf("%s", &input);
  int i = 4;
  int k = 0;
  while (i>0) {
    revInput[k] = input[i];
      i--;
      k++;
}
k++;
revInput[k] = '\0';
printf("Reversed:  %s\n", revInput);
}
3 Answers

There are several question to address in your code, let's go at them in order:

  • Firstly scanf with %s specifier is a dangerous proposition as it's very easy to cause a buffer overflow leading to undefined behavior.

  • Keep in mind that a 4 character string will need an array of size 5 because it needs space for the null byte.

  • Then, if you reverse to the point you also reverse the null byte at the end of the original buffer, that means that it will be placed at the beginning of the destination buffer and will make it an empty string as far as printf is concerned.

  • Finally the while loop must allow i to get to 0, otherwise revInput[0] will not be filled.

So correcting your code, it would look something like this:

Live demo

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

#define SIZE 5

int main(void) {

  printf("\nPlease enter a four digit number:\n");

  char input[SIZE];
  char revInput[SIZE];

  scanf("%4s", input); // %4s specifier will only parse 4 chars and add 
                        // the null byte as the 5th
  
  int i = SIZE - 2; // i will go from 3 to 0, the null byte at index 4 will
                    // not be reversed
  int k = 0;
  while (i >= 0) {
    revInput[k] = input[i];
    i--;
    k++;
  }
  k++;
  revInput[k - 1] = '\0'; // -1 because of k's last increment
  printf("Reversed:  %s\n", revInput);
}

If you wanted a more robust solution, for example, you don't know the exact size of the input, you could make a small tweak to your code to adapt it to variable sized input:

Live demo

int main(void) {

  printf("\nPlease enter a four digit number:\n");

  char input[SIZE];
  char revInput[SIZE] = {0}; // zero out the dest array

  scanf("%4s", input);

  int i = strlen(input); // i at last index of input, the null byte
  int k = 0;

  while (i-- >= 0) {
    revInput[k++] = input[i];  
  }
  printf("Reversed:  %s\n", revInput);
}

One last trick you could use, is to get the length of the string directly from scanf without the need for strlen:

Live demo

#include <stdio.h>

#define SIZE 5

int main(void) {
  printf("\nPlease enter a four digit number:\n");

  char input[SIZE];
  char revInput[SIZE] = {0};  // zero out the dest array

  int i;
  int k = 0;

  // lets add a condition to make sure scanf is successful
  if (scanf("%4s%n", input, &i) > 0) { 
    while (--i >= 0) {
      revInput[k++] = input[i];
    }
    printf("Reversed: %s\n", revInput);
  }
}

Your input buffer is too small.

For the scanf call, you need 4 characters (digits) + 1 for the null byte.

In the while loop, you access input via i. i is initially set to 4 (the fifth element, which is outside of your buffer).

  1. You need one char more to store the null character which terminates the string.
  2. You do not need second char array to reverse the string.
  3. Use functions to implement it
  4. You do not need & when pass char array to scanf
char *reverse(char *str)
{
    char *wrk = str;
    char *end = str;
    
    if(str && *str)
    {
        while(*(end + 1)) end++;
        while(end > wrk)
        {
            char ch;
            ch = *end;
            *end-- = *wrk;
            *wrk++ = ch;
        }
    }
    return str;
}

int main(int argc, char const *argv[])
{
  char input[5];
  printf("\nPlease enter a four digit number:");
  scanf("%4s", input);
  printf("\nReversed:  %s\n", reverse(input));
}
Related