3

I am trying to do something as simple as printing the reverse of a string . EXAMPLE :

Hello World! This is me

Needed O/P:

me is This World! Hello

My code goes something like this:

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

int main(){
 char *arr[20] ;
 int i,j;
 int size;
 char *revarr[20];
 printf(" enter the number of words\n");
 scanf("%d",&size);
 for(i=0;i<size;i++)
 scanf("%s",&arr[i]);
 for(i=0;i<size;i++)
 {

    printf("%s\n",&arr[size-1-i]); //overwritten words
    revarr[i]=arr[size-1-i];
 }
 printf(" the reversed sentence is %s\n",(char *)revarr);
}

I except arr[0] , arr[1] etc to be separate entities but on printing and storing them they seem to be overlapping like this : i/p:

Hello World

o/p:

World
HellWorld
the reversed sentence is WorlHell@#$

I can't seem to figure out what is wrong! Thanks in advance!

EDIT : On printing

printf(&arr[0]);
printf(&arr[1]);

I get :

HellWorld
World

What I expected it to print is

Hello
World
joanOfArc
  • 467
  • 1
  • 6
  • 16

4 Answers4

8

You declared arr and revarr as array of char pointers. You need to dynamically allocate memory for their elements.
Also note that you do not need & in statements

scanf("%s",&arr[i]);  

and

printf("%s\n", &arr[size-1-i]);  
//             ^No need of &  

Here is the modified version of your code. Note that there is no need to use revarr to reverse the string.

#include<stdio.h>
#include<stdlib.h>

int main(){
    size_t i, size;
    printf("Enter the number of words\n");
    scanf("%d", &size);
    char *arr[size] ;  // Variable length array. Supported by C99 and latter

    for(i = 0; i < size; i++) 
    {
        arr[i] = malloc(20); // Assumimg words are no longer than 20 characters
        scanf("%s", arr[i]);
    }

    printf("The reversed sentence is:\n");  
    for(i = size-1; i >= 0; i--)  // Run loop in reverse order and print words
        printf("%s ", arr[i]); 
}
haccks
  • 104,019
  • 25
  • 176
  • 264
2

You haven't allocated memory for arr[0], arr[1], etc. before using them to read strings in

scanf("%s",&arr[i]);

That is cause for undefined behavior. You need something like:

int main(){
   char *arr[20] ;
   int i,j;
   int size;
   char *revarr[20];
   printf(" enter the number of words\n");
   scanf("%d",&size);
   for(i=0;i<size;i++)
   {
      // Allocate memory.
      // make it large enough to hold the input
      arr[i] = malloc(100);
      scanf("%s", arr[i]);
   }
   for(i=0;i<size;i++)
   {
      revarr[i]=arr[size-1-i];
   }

   printf(" the reversed sentence is: ");
   for(i=0;i<size;i++)
   {
       printf("%s ", revarr[i]);
   }
   printf("\n");


   // Deallocate the memory.
   for(i=0;i<size;i++)
   {
      free(arr[i]);
   }

   return 0;
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 2
    `printf(" the reversed sentence is %s\n",(char *)revarr);` does not work – Weather Vane Dec 24 '14 at 20:36
  • ...apart from the missing `return 0;` ;-) – Weather Vane Dec 24 '14 at 20:41
  • why can't i use typecast to (char *) and then print revarr? is it because of the '\0' scanf will append after every word which will not let me printf the entire statement? – joanOfArc Dec 24 '14 at 20:43
  • 1
    because `revarr[]` is an array of pointers to each word (string). That is why @RSahu made a loop to print each with `for(i=0;i – Weather Vane Dec 24 '14 at 20:44
  • `return 0;` can be omitted. – haccks Dec 24 '14 at 21:07
  • @haccks why? Is there a default return value from `main()`? – Weather Vane Dec 24 '14 at 21:10
  • @WeatherVane, `return 0;` is assumed **only for** `main` when the last statement is not a `return` statement. – R Sahu Dec 24 '14 at 21:11
  • @WeatherVane; C11: **5.1.2.2.3 Program termination:** *If the return type of the `main` function is a type compatible with `int`, a return from the initial call to the `main` function is equivalent to calling the `exit` function with the value returned by the `main` function as its argument;11) **reaching the `}` that terminates the `main` function returns a value of 0**. If the return type is not compatible with `int`, the termination status returned to the host environment is unspecified.* – haccks Dec 24 '14 at 21:17
  • @haccks it's now off topic, but I was intrigued by the phrasing "a return from the *initial* call to the main function..." so I just tried a `main()` recursing (terminated by a static var) and it worked! – Weather Vane Dec 24 '14 at 21:28
  • @WeatherVane; You can call `main` inside `main` but you should note that there must be a condition that does not call `main` to terminate the program. And if it is the case then the return from the initial call to `main` will result in program termination. If it is not the case, then program will never return and runs infinitely. – haccks Dec 24 '14 at 21:39
  • @haccks I tried it with this `main()` that lacks a return value, and every call returns 0. `int i; int main(){ printf("i=%d\n",i++); if(i<5) printf("main=%d\n",main());}` – Weather Vane Dec 24 '14 at 21:47
  • @WeatherVane; I think you misread the text. It says: **a return from the initial call to the main function is equivalent to calling the exit function**: That means that only initial the return value from the initial call exits the program. Return value from other calls will not terminate/exit the program. – haccks Dec 24 '14 at 21:50
  • @haccks yes but what does it say about the undefined return value? – Weather Vane Dec 24 '14 at 21:52
  • @WeatherVane; Read [this](http://stackoverflow.com/a/8844963/2455888) and [this](http://programmers.stackexchange.com/a/203108). After that you will realize that the return type of `main` should be compatible with `int` – haccks Dec 24 '14 at 21:56
  • @haccks that wasn't my question. Clearly `int main()` is defined as returning an `int` type. Reading more carefully your quote *"C11: 5.1.2.2.3 Program termination ... reaching the } that terminates the main function returns a value of 0."* So if there isn't an explicit `return 0;` then in the case of `int main()` it will be done for you. As my tests concluded. Thanks for the input. – Weather Vane Dec 24 '14 at 22:16
2

This is a good approach for your problem :

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

int main(int argc, char *argv[])
{
     /* the string line will contain the line of the  input */
     char line[100];
     /* read the string with the function f gets */
     fgets(line,100,stdin);
   /* the tab will contain all the string of the variable  line */
     char *tab[20];
     /* the variable p will point to each string of the  line */
     char *p=NULL;
     /* we extract the strings of the line via the function strtok */
     p=strtok(line," ");
     int nb=-1;
     while (p!=NULL)
     {
         nb++;
         /* we allocate a space memory fo every str ing  */
            tab[nb]=malloc(sizeof(char)*100);
            strcpy(tab[nb],p);
            p=strtok(NULL," ");
     }
     /* there is an exception with the last string of the line we need to take care o f it */
     tab[nb][strlen(tab[nb])-1]='\0';
     int i;
     /* print the strings in reverse or der  */
     for (i=nb;i>=0;i--)
     {
         printf("%s ",tab[i]);
        /* dont forget to free the space memory at the end of the prog ram  */
         free(tab[i]);
     }
     printf("\n");

     return 0;
}
user12448
  • 511
  • 1
  • 4
  • 12
1

You need the following

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

int main(void) 
{
    size_t size;

    printf( "enter the number of words: " );
    scanf( "%zu", &size );

    char arr[size][20];
    char revarr[size][20];

    for ( size_t i = 0; i < size; i++ ) scanf( "%s", arr[i] );

    printf( "\n" );

    for ( size_t i = 0; i < size; i++ ) strcpy( revarr[i], arr[size-i-1] );

    printf( "the reversed sentence is"  );

    for ( size_t i = 0; i < size; i++ ) printf( " %s", revarr[i] );
    printf( "\n" );

    return 0;
}

If to enter

2
Hello World

then output will be

World Hello

Take into account that the code will be compiled only if your compiler supports C99. Otherwise you have to allocate memory dynamically for character arrays.

As for your code then it has undefined behaviour and in whole is invalid. You did not allocate memory for each element of arrays arr and revarr. You may not assign one array to another. Instead you have to use standard function strcpy and so on.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Yeah the solution looks good for C. Plus for size_t i might have to import a different header file i guess. Thanks! – joanOfArc Dec 24 '14 at 20:56
  • but I thought that defining variable inside for loop is only for C++! Am I right ? – user12448 Dec 24 '14 at 20:58
  • @joanOfArc In fact it is the best solution because it is more close to your code where you did not allocate dynamically arrays. It is based on variable length arrays. Of course it would better to use fgets but in this case the program would be more complicated. – Vlad from Moscow Dec 24 '14 at 21:00
  • @user12448 I wrote in my answer that the compiler should support C99. Otherwise some minor changes are needed. – Vlad from Moscow Dec 24 '14 at 21:02
  • @VladfromMoscow I admit it I was wrong !! sorry !! – user12448 Dec 24 '14 at 21:04
  • @joanOfArc the `size_t` is declared in the standard library `stddef.h` but you don't have to include it because it is present in the `stdio.h` – user12448 Dec 24 '14 at 21:07
  • @VladfromMoscow in your code size you are inputting "number of words". So shouldnt that be a[20][size]? – joanOfArc Dec 25 '14 at 03:52
  • 1
    @joanOfArc 20 is the maximum size in bytes of each words. That is you could define for example char word[20]; And you are asking the user how many words you are going to enter. So size is the number of words. As a result you will get char word[size][20] – Vlad from Moscow Dec 25 '14 at 05:56