-2

Is there any way of reversing a string in C with minimum (probably one-liner) source lines of code. C++ supports that by using #include <algorithm> as suggested here. I wonder if C too supports any such mechanism.

Community
  • 1
  • 1
Nagaraju
  • 1,853
  • 2
  • 27
  • 46

7 Answers7

7

Here's a one liner (of sorts, need to declare variables) that doesn't use any library functions:-

char s [] = "hello world";
char *p,*q;
for (p=s,q=0;p>q;q?*p^=*q,*q^=*p,*p--^=*q++:!*++p?q=s,*--p:0);

An explanation of how the code works:-

Variables:-

  • p: end of string pointer, initialised to the start of the string and is used to find the end
  • q: two pruposes, points to start of string and used for state

States:-

  • q == 0: for loop is searching for the end of the input string, p is being incremented to find end
  • q != 0: for loop is swapping characters from the first half of the string and the second half of the string

Termination:-

Loop terminates when the pointer to the first half of the string is beyond the pointer to the second half of the string. Whilst searching for the end of the string, the pointer to the first half (q) is 0, so the condition is always true.

Incrementing:-

The third part of the for loop is dependent on the state and can be broken down like this:-

if state is searching for end of string (q == 0)
  increment end of string pointer (++p)
  if end of string pointer is pointing at null terminator (*p == 0)
    set start of string pointer and set state to swapping characters (q=s)
    decrement end of string pointer (--p)
  endif
else
  swap characters (the three ^=)
  move first and secondhalf pointers (--p, ++q)
endif

The reason for the apparently unnecessary * in the *--p is to ensure all the parts of the ternary operators have the same type.

If you understand all that, then you should spot the bug in the code.

Skizz
  • 69,698
  • 10
  • 71
  • 108
5

A "minimum number of lines" requirement doesn't make that much sense (after all, your entire program can be written in one line). If you're willing to go for an in-place reversal you can have a fairly lightweight implementation though:

void strrev(char *s) {
    char *p = s + strlen(s);
    while ( s + 1 < p ) {
        char tmp = *s;
        *s++ = *--p;
        *p = tmp;
    }
}
Frerich Raabe
  • 90,689
  • 19
  • 115
  • 207
  • 2
    +1 but function names should not start with `str`, they are reserved for future. http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html – ShuklaSannidhya Jul 17 '13 at 10:48
3
#include <string.h>
char *strrev(char *string);

Description strrev reverses the order of the characters in the given string. The ending null character (\0) remains in place.

Returns

strrev returns a pointer to the altered string. There is no error return value

THIS WORKS FOR WINDOWS ONLY

Coffee_lover
  • 545
  • 6
  • 15
2

No, there is no standard C library routine for reversing a string (or other sequences or ranges.)

Nikos C.
  • 50,738
  • 9
  • 71
  • 96
1
#include <stdio.h>

int strrev_r(char *str, int pos){
    char ch = str[pos];
    return (ch == '\0')? 0 : ((str[pos=strrev_r(str, ++pos)]=ch), ++pos);
}
void strrev(char *str){
    strrev_r(str, 0);
}

int main(){
    char string[] = "string";
    strrev(string);
    puts(string);
    return 0;
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
0

Hello this is not one line but it work perfectly

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

char *revstr(char *str)
{
  int   i;
  int   size;
  int   max;
  char  save;

  i = 0;
  size = strlen(str);
  max = size / 2;
  while (i < max)
    {
      save = str[i];
      str[i] = str[size - 1 - i];
      str[size - 1 -i] = save;
      i = i + 1;
    }
  return(str);
}

int main()
{
  char *str;

  str = strdup("hello");
  str = revstr(str);
  printf("%s\n", str);
}
Nagaraju
  • 1,853
  • 2
  • 27
  • 46
Saxtheowl
  • 4,136
  • 5
  • 23
  • 32
0

If you insist one a one liner, you will get a one liner.

for(int i = -1, len = strlen(s), t = 0; ++i < len / 2; t = s[i], s[i] = s[len - 1 - i], s[len - 1 - i] = t);
Amarghosh
  • 58,710
  • 11
  • 92
  • 121