0

I've been trying to "copy" one string to another, in reverse. It kindof works, but it prints some weird symbols. I've tried setting char copy[length2] but that makes the program not run at all.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define ARR_SIZE 50

int main()
{
    char string[ARR_SIZE];
    printf("Enter char array!\n");
    fgets(string, ARR_SIZE, stdin);

    string[strlen(string) - 1] = '\0';
    int length = (strlen(string) - 1);
    int length2 = (strlen(string) - 1);

    printf("%s\t%d\n", string, length);

    for (int i = 0; i <= length; i++)
    {
        printf("INDEX = %d   CHAR = %c\n", i, string[i]);
    }
    
    printf("%d", length2);
    char copy[ARR_SIZE];
    
    for (int i = 0; i <= length2; i++)
    {
        copy[i] = string[length];
        length--;
    }

    


    printf("\n%s", copy);
}

enter image description here

  • 4
    Check the null-termination in `copy`. – Sourav Ghosh Nov 02 '21 at 15:27
  • @thebusybee: It's not nonsense; `fgets` always puts in the NUL terminator when it reads a line, so `string[strlen(string) - 1] = '\0';` is basically Perl's `chop`; it unconditionally removes the final character from the string (presumably assumed to be a newline). It's going to trigger undefined behavior if you're at EOF though (better not hit Ctrl-D immediately, or run with `< /dev/null`); the array won't be initialized at all (`fgets` doesn't NUL it on EOF/error); even if it was zeroed, the code would write one character *before* the array. And it would misbehave if no newline was entered. – ShadowRanger Nov 02 '21 at 15:46
  • @thebusybee I'm afraid your comment is wrong/misleading. `string[strlen(string) - 1]` just removes the `\n` at the end provided there is one. OTOH this is not the best method for removing the `\n`. The best method is shown here: https://stackoverflow.com/a/28462221/898348 – Jabberwocky Nov 02 '21 at 15:59
  • your `length` and `length2` variables are misleading. `strlen` does _not_ include the `NUL` terminator in its calculation, so saying `length = strlen(..) - 1` is one too few of that actual string length. – yano Nov 02 '21 at 16:01

2 Answers2

1

These are the minimal modifications I'd make to your code:

#include <stdio.h>
#include <string.h>
// remove unneeded headers

#define ARR_SIZE 50

int main(void)
{
    char string[ARR_SIZE];
    printf("Enter char array!\n");
    fgets(string, ARR_SIZE, stdin);

    string[strlen(string) - 1] = '\0';
    // remove the -1 on the string length calculation, the NUL terminator is not
    // included in strlen's return value
    int length = strlen(string);
    // no sense in calling strlen twice
    int length2 = length;

    // fixed `length` now prints the correct length
    printf("%s\t%d\n", string, length);

    // change from <= to <. The array indices where the characters live are
    // [0, length-1].
    for (int i = 0; i < length; i++)
    {
        printf("INDEX = %d   CHAR = %c\n", i, string[i]);
    }
    
    // fixed `length2` now prints the correct length
    printf("%d", length2);
    char copy[ARR_SIZE];
    
    for (int i = 0; i < length2; i++)
    {
        // last character in `string` lives at the `length`-1 index
        copy[i] = string[length-1];
        length--;
    }

    // `length2` is the index after the last char in `copy`, this needs
    // to be NUL terminated.
    copy[length2] = '\0';

    // prints the reversed string
    printf("\n%s", copy);
}

Demo

yano
  • 4,827
  • 2
  • 23
  • 35
0
  1. Use functions.
  2. Terminate strings with null character \0 or simply 0.
char *copyreverse(char *dest, const char *src)
{
    size_t len = strlen(src);
    const char *end = src + len - !!len;
    char *wrk = dest;

    while(len--)
        *wrk++ = *end--;
    *wrk = 0;
    return dest;
}

int main()
{
    char dest[10];
    char *src = "hello";

    printf("`%s` reversed `%s`\n", src, copyreverse(dest, src));
}
0___________
  • 60,014
  • 4
  • 34
  • 74