0

I have created a code reverse a string but for some reason it is not working. But I think my logic is right. Then why is it not working??

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

int main() {
    char words[100];
    int i=0;
    printf("Enter a word/sentence: ");
    scanf("%s", words);

    while (words[i]!='\0') {
           ++i;
    }
    printf("\nThe Reverse is: ");
    while (i<=0) {
         printf("%s",words[i]);
         i--;
     }
     return 0;
}
3
  • scanf("%s".. -> scanf("%99s"..., lookup strlen Commented Aug 16, 2017 at 4:08
  • 3
    printf("%s",words[i]); --> printf("%c", words[i]); Commented Aug 16, 2017 at 4:09
  • 1
    while (i<=0) { is i always going to be greater than zero. Hence this condition is always false Commented Aug 16, 2017 at 4:16

2 Answers 2

3

While you already have an answer, there are a few additional points you need to consider before you have a solution that doesn't have the potential to invoke Undefined behavior.

First, always, always validate all user input. For all you know a cat could have gone to sleep on the 'L' key (with millions being entered), or a more likely case, the user just decides to type a 100-char sentence (or more) which leaves 'words' as an array of chars that is NOT nul-terminated and thus not a valid string in C. Your loop to get the length now invokes Undefined Behavior by reading beyond the end of words off into the stack until the first random '0' is encounter or a SegFault occurs.

To prevent this behavior (you should really just use fgets) but with scanf you can provide a field-width modifier to prevent reading more than length - 1 chars. This insures space for the nul-terminating character.

Further, the "%s" conversion-specifier stops conversion on the first whitespace character encountered -- making your "Enter a .../sentence" an impossibility because scanf ("%s", words) will stop reading after the first word (at the first whitespace.

To correct this problem (you should really just use fgets) or with scanf you can use a character class (stuff between [...]) as the conversion specifier that will read until a '\n' is encountered., e.g. scanf ("%[^\n]", words). However, recall, that is still not good enough because more than 99-chars can be entered leaving the string un-terminated at 100 and invoking Undefined Behavior at character 101 (off the end of the array).

To prevent this problem (ditto on fgets), or include the field-width modifier, e.g. scanf ("%99[^\n]", words). Now no more than 99-chars will be read regardless of the cat sleeping on the 'L' key.

Putting that altogether, you could do something like:

#include <stdio.h>

#define MAXC 100    /* if you need a constant, define one */

int main(void) {

    char words[MAXC] = "";
    int i = 0, rtn = 0;     /* rtn - capture the return of scanf  */

    printf ("Enter a word/sentence : ");
    if ((rtn = scanf ("%99[^\n]", words)) != 1) {   /* validate ! */
        if (rtn == EOF)     /* user cancel? [ctrl+d] or [ctrl+z]? */ 
            fprintf (stderr, "user input canceled.\n");
        else                    /* did an input failure occur ? */
            fprintf (stderr, "error: invalid input - input failure.\n");
        return 1;               /* either way, bail */
    }

    for (; words[i]; i++) {}    /* get the length */

    printf ("Reversed word/sentence: ");
    while (i--)
        putchar (words[i]);     /* no need for printf to output 1-char */
    putchar ('\n');

    return 0;
}

Example Use/Output

$ ./bin/strrevloops
Enter a word/sentence : My dog has fleas.
Reversed word/sentence: .saelf sah god yM

Look things over and let me know if you have any further questions.

Sign up to request clarification or add additional context in comments.

6 Comments

The answer couldn't have been clearer. I just want to ask if there is any specific reason for the string initialiser for words ?
You always want to initialize your arrays to all zero, that way regardless of any error in logic, if you read less than sizeof (array) chars, your string will always be nul-terminated :)
Fair enough, just that for automatic arrays (of good enough size), it will be expensive. Nevertheless a good practice.
Initialization is cheap from an efficiency standpoint. Using the default initializer, whether with words = "" or words = {0} accomplishes the same thing. When you initialize to zero, you are only initializing the first element, all remaining elements are made zero by the default initialization process -- lightning fast, and well worth the 0.00472 microsecond or initialization time (or whatever it is in the real world).
"your string will always be nul-terminated" --> maybe. Consider if (rtn == EOF), on input error, the contents of words is not certain. As much as initializing variables is a worthy guide (I an not a fan off initializing large arrays when words[0] = 0; would suffice and perhaps 100x faster), checking return values is even more beneficial.
|
1

There are few mistakes in your program.

  1. After you have reached the end of the string.You should do i-- as your array index of i will be pointing to '\0'.

  2. Your while loop checks for <= but it should be >=.

  3. Use %c for printing chararcters. %s is used to print strings and not char.


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

int main() {
    char words[100];
    int i=0;
    printf("Enter a word/sentence: ");
    scanf("%s", words);

    while (words[i]!='\0') {
        ++i;
    }
    i--;
    printf("\nThe Reverse is: ");
    while (i>=0) {
       printf("%c",words[i]);
       i--;
    }
 return 0;
}

3 Comments

Always, always validate user input. int rtn; if ((rtn = scanf ("%s", words)) != 1) { if (rtn == EOF) { /* handle user canceled input */ }; /* handle input failure */} Then the loops, for (; words[i]; i++) {}; while (i--) printf ("%c", words[i]); (there is no need for stdlib.h in the code)
Seems odd to add i--; before the loop when while (i>0) (without =) would do the job.
@chux without i--, i would be pointing to '\0'. As David C. Rankin said while(i--) would do the job.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.