0

I want to reverse a string in the C language. I'm kinda new, so I would love to get some help and explanation. Why doesn't my solution work?

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

char *rev(char *str) {
  char *q = str;
  int len = strlen(str);
  char *p = (char*)calloc(len+1, sizeof(char));
  int j=0;
  if (NULL == str || len == 1) return str;
  for (j = len+1 ; j > 0 ; j-- ) {
    p[j]=*q;
    q++;
  }
  return p;
}

int main(int argc, char **argv){
  char *t = argv[1];
  char *p ;
  printf("%s",t);
  p=rev(t);
  printf("%s",p);
  getchar();
  return 0;
}

It's not working :(

0

3 Answers 3

3

First, you were smart to use calloc to make sure your result buffer had a zero at the end.

But it also put the zero at the beginning!

Your loop termination condition was j > 0 meaning you never filled slot 0 in the result.

So when you try to print p, the first character in the buffer it points to contains a \0 -- marking the end of a string, so your result is always the empty string.

I've done a little "fix" at http://codepad.org/QppfYQkm (I did not change the formatting, and I hardcoded the argument so it would be self-contained.)

Aside: I removed your check for if (len == 1) return str. Do not do this! If you have a one-character string, you will be returning the same buffer as that which held your argument, meaning changes to that result would destroy your input. Keep these buffers separate.

You were really close. :)

ADDENDUM

Here is some code using a commandline argument:

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

char *rev(char *str) {
  char *q = str;
  int len = strlen(str);
  char *p = (char*)calloc(len + 1, sizeof(char));
  int j;

  if (NULL == str) return NULL;

  for (j = len-1 ; j >= 0 ; j--) {
    p[j] = *q;
    q++;
  }
  return p;
}

int main(int argc, char **argv) {
  if (argc > 1) {
    char *t = argv[1];
    char *p ;

    printf("%s\n",t);
    p = rev(t);
    printf("%s\n",p);

    return 0;
  }
}

When I run it:

$ gcc rev.c && ./a.out "hello there, reverse me"
hello there, reverse me
em esrever ,ereht olleh
$ gcc rev.c && ./a.out ""


$ gcc rev.c && ./a.out
$

The program works fine with text and with the empty string. It silently does nothing when given no argument.

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

3 Comments

thanks!! a little thing that doesnt work - if I change the string "reverse me" to : char * sp = argv[1] - I get an error - the program breaks immediately, why does this happen ? how can I get the string input from the user?
You should be able to say char* t = argv[1]; and the code will work fine provided you pass a command line argument. Otherwise it will segfault. To make your code robust, you should start main with a check to make sure argc > 1.
Working example added to answer.
2

You have to be careful with your indices at the boundaries.

One way to fix is replace your for line with this:

for (j = len-1; j >= 0 ; j-- )

Comments

0

You need to iterate over half the list (rounding down, the middle character can't be reversed if it's an odd-lengthed string), and then swap it via a temporary variable.

You are writing over half your string because you're not using a temporary variable. Try something like:

for( j = 0; j < len / 2; ++j ) {
    char tmp = p[ j ];
    p[ j ] = p[ len - j - 1 ];
    p[ len - j - 1 ] = tmp;
}

Edit: this does it in place; if you were doing it into another buffer you'll need to add p[len] = 0;

2 Comments

This is a tested & working piece of code, a comment on why it was marked down would be nice ;)
Not my downvote, but the OP asked why his or her code did not work, and that code created a new buffer and copied in the source characters in reverse order. Your in-place reverse does work, but it would require that the OP first allocate a new buffer, copy the source characters in, and then reverse them via swapping. The downvoter thought the answer was therefore not helpful to the question being asked despite being a good in-place reversal technique.

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.