Search code examples
ccommand-line-argumentsreversec-stringsfunction-definition

C Program to print string from commandline in reverse


/* Pgm to print string from commandline and reverse it */
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>

int main(int argc, char *argv[]) {
  if(argc<1){
    perror("Not enough arguments");
  }
  // Printing the string
  for(int i=1; i<argc ; i++){
   printf("%s\n",argv[i]);
  }
  //Part to print the string in reverse
  char *arr = (char*) malloc(sizeof(argv[1])+1);    // +1 for the NULL terminator
  strcpy(arr,argv[1]);
  char *str = (char*) malloc(sizeof(argv[1])+1);       //buffer array

//Reverse part begins
int j=0;
  for(int i= sizeof(argv[1]); i>=0 ; i--){
    str[j] = arr[i];
    j++;
  }

  for(int j=0;j<sizeof(argv[1]);j++){        // Printing the reverse string
  printf("R=%s\n",&str[j]);
 }

  free(arr);
  free(str);
  return 0;
}

This program is expected to print the text from argv[1] on commandline in reverse order. But the output I get is weird. output

user@DESKTOP-KI53T6C:/mnt/c/Users/user/Documents/C programs$ gcc linex.c -o linex -Wall -pedantic -std=c99
user@DESKTOP-KI53T6C:/mnt/c/Users/user/Documents/C programs$ ./linex hello
hello
R=
R=
R=
R=
R=olleh
R=lleh
R=leh
R=eh

Also when the input is above a certain number of characters, it automatically truncates it:

user@DESKTOP-KI53T6C:/mnt/c/Users/user/Documents/C programs$ ./linex strcmpppssdsdssdsd
strcmpppssdsdssdsd
R=spppmcrts
R=pppmcrts
R=ppmcrts
R=pmcrts
R=mcrts
R=crts
R=rts
R=ts

All I want is the output to be : 'olleh' when I type 'hello'


Solution

  • The expression argv[1] has the type char *. That is it is a pointer. sizeof( char * ) that is equivalent to the expression sizeof( argv[1] ) is equal to 4 or 8 depending on the used system.

    So for example in this line

    char *arr = (char*) malloc(sizeof(argv[1])+1);
    

    there are allocated not enough memory to store a string pointed to by the pointer argv[1]. Instead of the expression sizeof( argv[1] ) you need to use expression strlen( argv[1] ).

    Also to output a string in the reverse order there is no any need to allocate dynamically a character array. This is just a bad idea.

    Here is a demonstrative program that shows how to output a string in the reverse order.

    #include <stdio.h>
    #include <string.h>
    
    int main(void) 
    {
        const char *s = "Hello";
        
        for ( size_t i = strlen( s ); i != 0; )
        {
            putchar( s[--i] );
        }
        
        putchar( '\n' );
        
        return 0;
    }
    

    The program output is

    olleH
    

    If you want not just to output a string in the reverse order but to create a new string in the reverse order then what you need is to write a function that performs copying of a string stored in one character array into another character array.

    Here is a demonstrative program.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    char * copy_reverse( char *s1, const char *s2 )
    {
        size_t n = strlen( s2 );
        
        s1[n] = '\0';
        
        while ( *s2 ) s1[--n] = *s2++;
        
        return s1;
    }
    
    int main(void) 
    {
        const char *s1 = "Hello";
        
        char *s2 = malloc( strlen( s1 ) + 1 );
        
        if ( s2 ) puts( copy_reverse( s2, s1 ) );
        
        free( s2 );
    
        return 0;
    }
    

    The program output is the same as shown above

    olleH