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

void main(void)
{
    char in[15], rev[15];

    printf("Enter a word (upto 15 letters): ");
    gets(in);
    
    for (int i = 0, j = 15; i < strlen(in); i++, j--)
    {
        rev[i] = in[j];
    }
    puts(rev);
}

Shows no error, just not working. What am I doing wrong?

Edit : no strrev

Rahul
  • 15
  • 1
  • 5
  • 3
    First of all, never ***ever*** use the `gets` function. It's considered so [dangerous](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) that it has even been removed from the C specification. Use e.g. `fgets` instead. – Some programmer dude Apr 20 '22 at 11:35
  • 1
    Also remember that the size when declaring arrays is the actual size, not the top index. So for your arrays, the index `15` will be out of bounds. And what happens if the user only enters a few (less than 14) characters? Will you still copy the uninitialized parts of the input array? And what about the null-terminator, what happens with it? – Some programmer dude Apr 20 '22 at 11:35
  • 2
    You start from `j = 15`, regardless of the length of the string read. – DevSolar Apr 20 '22 at 11:36
  • 2
    Also, rev must be terminated with the NULL character. – Arnabjyoti Kalita Apr 20 '22 at 11:36
  • Lastly, if you only want to print the reversed input, begin printing character by character from the last position to the first (i.e. from index `strlen(in) - 1` to `0`). – Some programmer dude Apr 20 '22 at 11:38

2 Answers2

1

For starters according to the C Standard the function main without parameters shall be declared like

int main( void )

The function gets is unsafe and is not supported by the C Standard. Instead use either scanf or fgets.

The function strlen is a standard C string function. So according to the requirement you may not use it.

You are not reversing a string. You are trying to copy a string in the reverse order into another string.

The program can look the following way

#include <stdio.h>

int main(void)
{
    enum { N = 15 };
    char in[N] = "", rev[N];

    printf("Enter a word (upto %d letters): ", N - 1 );
    scanf( " %14s", in );

    size_t n = 0;
    while ( in[n] ) ++n;

    rev[n] = '\0';

    for ( size_t i = 0; i < n; i++ )
    {
        rev[n - i - 1] = in[i];
    }

    puts( rev );
}

If you actually need to reverse a string in place then the program can look the following way

#include <stdio.h>

int main(void)
{
    enum { N = 15 };
    char in[N] = "";

    printf("Enter a word (upto %d letters): ", N - 1 );
    scanf( " %14s", in );

    size_t n = 0;
    while ( in[n] ) ++n;

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

    puts( in );
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • I am new to C. So sorry about this. But what does this do? scanf( " %14[^\n]", in ); . %14[^\n] part – Rahul Apr 20 '22 at 11:52
  • 1
    @Alex It means to read at most 14 characters or until the Enter key pressed. In this case the new line character '\n' that is placed in the input buffer as a result of pressing the Enter key will not be read. – Vlad from Moscow Apr 20 '22 at 11:54
  • @VladfromMoscow "_Instead use either `scanf` or `fgets`._" Never `scanf`. Actually, it can be as unsafe as `gets`. – Zakk Apr 20 '22 at 12:12
  • @Zakk And how can this call of scanf scanf( "%14s", in ); be unsafe? – Vlad from Moscow Apr 20 '22 at 12:15
  • @VladfromMoscow Not this call. It just _can_ be as unsafe as `gets`. For example, `scanf("%s", in);`. – Zakk Apr 20 '22 at 12:17
  • @Zakk So why not to use scanf if to use it correctly? – Vlad from Moscow Apr 20 '22 at 12:18
  • @VladfromMoscow Yes, of course. But the point here is to use it _correctly_. Btw, the code you showed has some problems. – Zakk Apr 20 '22 at 12:20
  • @Zakk What problems? – Vlad from Moscow Apr 20 '22 at 12:24
  • @VladfromMoscow For example, if the user enters a string containing spaces, it reads everything up to the first space. This is because `scanf` is programmed in a way that it stops _parsing_ the input when it encounters either a newline, a tab, a space or `EOF`. – Zakk Apr 20 '22 at 12:28
  • @VladfromMoscow Another example is if the user enters more than `N` characters. In this case, `scanf()` doesn't remove the remaining characters from the buffer, thus another call to `scanf()` would result in it reading those. – Zakk Apr 20 '22 at 12:29
  • @Zakk In the program clear written "Enter a word" – Vlad from Moscow Apr 20 '22 at 12:30
  • @VladfromMoscow NEVER TRUST the user input. – Zakk Apr 20 '22 at 12:30
  • @Zakk fgets also does not remove remaining characters. – Vlad from Moscow Apr 20 '22 at 12:30
  • @VladfromMoscow Yes. It's up to you to clear them. – Zakk Apr 20 '22 at 12:33
0

EDIT: getline is not standard C, and it is only recognized by POSIX systems. Another solution is to use fgets that works for both OSes. I provided both examples.

As others have already pointed out, you are making some mistakes:

  • Unsafe practice when getting input from the user.
  • Always starting from 15 even if the input string has less chars.

I have created a little example with dynamic allocation that works with more than 15 characters and fixes the afore-mentioned issues. Comments inline to key points.

Example: getline - POSIX

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

int main (int argc, char *argv[]) {

    // Idea from https://stackoverflow.com/questions/7709452/how-to-read-string-from-keyboard-using-c
    char *line = NULL;  /* forces getline to allocate with malloc */
    size_t len = 0;     /* ignored when line = NULL */
    ssize_t read;

    read = getline(&line, &len, stdin);

    if (read > 0)
    {
        printf ("\n  String from user: %s\n",  line);
    }else
    {
        printf ("Nothing read.. \n");
        return -1;
    }    

    // Now we need the same amount of byte to hold the reversed string
    char* rev_line = (char*)malloc(read);
    
    // "read-1" because we start counting from 0. 
    for (int i = 0, j = read-1; i < read; i++, j--)
    {
        rev_line[i] = line[j];
    }
    printf("%s\n",rev_line);

    free (line);  /* free memory allocated by getline */
    free(rev_line);

    return 0;
}

Example: fgets - C standard

fgets does not return the number of characters read, so it has to be chained with strlen to decide how many characters to allocate for the reversed string.

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

int main (int argc, char *argv[]) {

    char line[LINE_MAX];
    size_t len = 0;     /* ignored when line = NULL */
    ssize_t read;


    if (fgets(line, LINE_MAX, stdin) != NULL)
    {
        line[strcspn(line, "\n")] = '\0'; //fgets() reads the \n character (that's when you press Enter). 
        read = strlen(line);
        printf ("\n  String from user: %s\n",  line);
    }else
    {
        printf ("Nothing read.. \n");
        return -1;
    }    

    // Now we need the same amount of byte to hold the reversed string
    char* rev_line = (char*)malloc(read);

    for (int i = 0, j = read-1; i < read; i++, j--)
    {
        rev_line[i] = line[j];
    }
    printf("%s\n",rev_line);

    free(rev_line);

    return 0;
}
Fra93
  • 1,992
  • 1
  • 9
  • 18