-1

I have been trying to reverse(and print it that way) a given string only using for loops and nothing more. I think I have built up the basic logic, but it has some defects. When run, it only reverses the first two characters and then stops. Please help me find the defect in my logic.

#include<stdio.h>
#include<stdlib.h>
int main()
{
    char a[20];
    int i;
    printf("Enter any String\n");
    gets(a);
    for(i=0;a[i]!=NULL;i++)
    {}
    for(i=1;i>=0;i--)
    {
        printf("%c",a[i]);
    }
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Aniruddha
  • 774
  • 1
  • 7
  • 18
  • 1
    Do you need to _print_ it reversed or reverse it _in memory_? – Jabberwocky Nov 20 '19 at 08:18
  • 2
    Your first `for` loop has no effect since your second `for` loop starts by resetting the value of `i` to 1. – lurker Nov 20 '19 at 08:18
  • 1
    Hint: to print the string reversed, you need to print the last character of the string, then the second to last etc. until the first. Your second for loop does not do that at all., it prints the second character and then the first. – Jabberwocky Nov 20 '19 at 08:21
  • @Jabberwocky How do I get to that last character? – Aniruddha Nov 20 '19 at 08:27
  • 1
    Hint 2: you need a separate variable for the length of the string, call it `length`. With the first for loop you determine the length of the string; after that for loop `i` contains the length of the string. Store that in the `length` variable. Then loop through the string from `length-1` to `0` instead of from `1` to `0`. – Jabberwocky Nov 20 '19 at 08:32
  • 2
    Your source of learning C is outdated by some 30 years. Never use `gets`, that function doesn't even exist since 8 years back. – Lundin Nov 20 '19 at 08:53
  • @Lundin What should I use instead of `gets()`? – Aniruddha Nov 20 '19 at 08:58
  • 2
    @dev.aniruddha The question you should be asking yourself is rather, "why was I taught to use `gets` and should I trust anything said from that source of learning from now on?". As for `gets` replacements, see [Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used). – Lundin Nov 20 '19 at 09:05
  • @Lundin I was actually just googling about it. Thanks for the recommendation. – Aniruddha Nov 20 '19 at 09:22

4 Answers4

4

For starters the function gets is not a standard C function any more. it is unsafe. Instead use the standard C function fgets. The function can append the new line character '\n' to the entered string that should be excluded from the string.

It is unclear from your question whether you are allowed to use standard string functions.

Nevertheless here is a demonstrative program that does the task without using standard C string functions and that uses only for loops (neither while loop nor do-while loop).

#include <stdio.h>

int main(void) 
{
    enum { N = 20 };
    char s[N];

    printf( "Enter any String less than %d symbols: ", N ); 

    fgets( s, N, stdin );

    //  remove the new line character and calculate the length of the string
    size_t n = 0;
    for ( ; s[n] != '\0' && s[n] != '\n'; ) ++n;

    s[n] = '\0';

    //  reverse the string
    for ( size_t i = 0; i < n / 2; i++ )
    {
        char c = s[i];
        s[i] = s[n-i-1];
        s[n-i-1] = c;
    }

    puts( s );

    return 0;
}

Its output might look the following way

Enter any String less than 20 symbols: Hello dev.aniruddha
ahddurina.ved olleH

If you want just to output the original string in the reverse order then the program can look like

#include <stdio.h>

int main(void) 
{
    enum { N = 20 };
    char s[N];

    printf( "Enter any String less than %d symbols: ", N ); 

    fgets( s, N, stdin );

    //  remove the new line character and calculate the length of the string
    size_t n = 0;
    for ( ; s[n] != '\0' && s[n] != '\n'; ) ++n;

    s[n] = '\0';

    //  reverse the string

    for ( ; n-- != 0;  )
    {
        putchar( s[n] );
    }

    putchar( '\n' );

    return 0;
}

Its output is the same as shown above

Enter any String less than 20 symbols: Hello dev.aniruddha
ahddurina.ved olleH
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • This deviates a bit from the original code, because of the use of fgets() instead of gets (which is better for many reasons). This makes it at places a little bit harder to follow. Also this solution reverses the string in memory not just on output. But a high quality answer that gives a good amount of insight.+1 – Kami Kaze Nov 20 '19 at 09:16
  • @KamiKaze hets is not a standard C function. So by the definition it can not be better. It is just very bad and unsafe. – Vlad from Moscow Nov 20 '19 at 09:21
  • I may have been unclear with my wording of the comment. I meant `fgets()` is far superior to `gets()` – Kami Kaze Nov 20 '19 at 09:24
  • @KamiKaze One more you shall not use the function gets. It is not a standard C function. It is unsafe. And many compilers can issue an error that the name is undeclared. – Vlad from Moscow Nov 20 '19 at 09:26
  • I totally agree, also that you added the version which just reverses the output improves the answer even more. – Kami Kaze Nov 20 '19 at 09:28
1

gets() is a bad idea as you can easily get overflows and it is no longer part of the c standard. So let's assume that the string entered fits the array and this is just for an excercise with no reallife usage.

Your first loop finds the terminator. That's good.
Your second loop sets the variable that indicates the terminator to 1, destroying the result. If you remove the assignment i=1, your program compiles with gcc and does what you want.

#include<stdio.h>
#include<stdlib.h>
int main()
{
    char a[20];
    int i;
    printf("Enter any String\n");
    gets(a);
    for(i=0;a[i]!=NULL;i++)
    {}
    for(;i>=0;i--) //removed i=1 here
    {
        printf("%c",a[i]);
    }
}

But there are still some issues to be addressed. You will also reverse the terminator, instead you should start from i-1 I would advise to not use a for loop if you do not have a counter criterion The first loop should rather be a while loop, but as it was part of the assignment you had no choice still I will replace it in my recommendation. As they can easily be swapped.

Then you could use another variable for the second loop for clarity. Also NULL is the NULL-pointer not the value 0 (also namend NUL apperantly) . So you should replace this either with 0 or with '\0'

Also stdlib.h is not required here

#include<stdio.h>
int main()
{
    char a[20];
    int i = 0;

    printf("Enter any String\n");
    gets(a);

    while (a[i] != 0)
    {
        i++;
    }

    for(int j = i-1; j>=0; j--) // -1 to get the value in front of the terminator
    {
        printf("%c",a[j]);
    }
    printf("\n"); //to flush the output.
}
Kami Kaze
  • 2,069
  • 15
  • 27
  • 1
    Details you left out: `NULL` -> `NUL` – Jabberwocky Nov 20 '19 at 08:42
  • Other detail: your solution actually prints the NUL which is not quite correct. Therefore no UV – Jabberwocky Nov 20 '19 at 08:44
  • @Jabberwocky what do you mean with `NULL -> NUL`? But yeah you are right I forgot to decrement before the first print. – Kami Kaze Nov 20 '19 at 08:48
  • `NULL` is the NULL _pointer_, `NUL` is the NUL _char_, but actually there is no `NUL` symbol, therefore it should just be `0`. And BTW he want only for loops, no while. – Jabberwocky Nov 20 '19 at 08:52
  • Depending on the platform `NULL`is defined as `0`, and therefore `NULL` compiles fine. – Jabberwocky Nov 20 '19 at 08:55
  • @Jabberwocky I know still it does not make sense to use in this context. I revised the answer now. Anymore issues with it? Trying to piece a good answer together while trying to be fast is nearly mutually exculsive... I should take more time to analyze. – Kami Kaze Nov 20 '19 at 09:00
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/202704/discussion-between-kami-kaze-and-jabberwocky). – Kami Kaze Nov 20 '19 at 09:31
-1

Here is the solution code. The first for loop is to be used for determining the length of the string and the second for loop is for traversing the string from the last position to the first.

#include<stdio.h>
int main()
{
    char a[20];
    int i,j,len;
    printf("Enter a String\n");
    gets(a);
    for(i=0;a[i]!=NULL;i++)
    {}
    len=i;
    for(j=len-1;j>=0;j--)
    {
        printf("%c",a[j]);
    }

}
Aniruddha
  • 774
  • 1
  • 7
  • 18
-1

I think why only two chars are been return is because of the condition statement in your second "for loop".

for(i=1;i>=0;i--) 

Note:

  1. it repeats from 1~0 (1,0): meaning it will repeat only twice
  2. first iteration: when i == 1
  3. second iteration: when i == 0 ; then it ends .

Please note that you created two "for loops" with the first one having no content.

Bonus: I tried to fixed your code but realized that my C language skills isnt the best lol . Anyways, i came up with something that you could reference but it only reverse strings of less than 8 elements.

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

int findlength(char a[]);

int main()
{
    char a[20];
    int i;
    printf("Enter any String\n");
    gets(a);
    int len = findlength(a);
    printf("Lenght of the String is: %d \n",len);
    printf("Reversed String is: ");
    for(i=len;i>-1;i--){
        printf("%c",a[i]);
    }

}

int findlength(char a[]){
    int result = 0;
    int i;
    for(i=0;i<sizeof(a) / sizeof(char);i++){ // sizeof(char) is 1 
        if(a[i] == '\0') //end of string
            return result;
        result += 1;
    }
    return result;
}
spil3141
  • 1
  • 1