Stanislav Fotev
Stanislav Fotev

Reputation: 21

Reverse String function in C without library functions

This is my task:

Realize function that reverses null terminated string. The prototype of the function is void Reverse(char *ptr);. Do not use standard library functions.

This is my code for now:

void Reverse(char *ptr) {
    char *newString;
    char ch = *ptr;
    unsigned int size = 0;

    for (int i = 1; ch != '\0'; i++) {
        ch = *(ptr + i);
        size++;
    }

    newString = (char*)malloc(size);

    for (int left = 0, right = size - 1; left < size; left++, right--) {
        *(newString + left) = *(ptr + right);
    }

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

It reverses the string and saves it in the newString

My first problem is that when I print the newString to see if the functions works the string is reversed, but after it there are some symbols.

For example: If I have char *str = "hello"; and Reverse(str); in the main method the result of printf("%s", newString) will be olleh****.

But if change the newString = (char*)malloc(size); to newString = (char*)malloc(1); it works fine.

My second problem is that I don't know how to save the newString into the given one. I am using a new String because the given one can't be changed.

Upvotes: 1

Views: 1883

Answers (4)

Tavij
Tavij

Reputation: 98

Simple string reverse function without string.h library functions :

#include <stdio.h>
void reverse(char *str, int n);
int main()
{
    char str[100];
    int n;
    printf("Enter a string\n");
    scanf("%s",&str);
    for( n = 0; str[n] != '\0'; n++)
    {

    }
    reverse(str,n);
    puts(str);
    return 0;
}
void reverse(char *str,int n)
{
    printf("Length = %d\n",n);
    printf("Reversed :\n");
    int i;
    char ch;
    for(i = 0; i<n/2; i++)
    {
        ch = str[i];
        str[i] = str[n-i-1];
        str[n-i-1] = ch;
    }
}

Upvotes: 0

Vlad from Moscow
Vlad from Moscow

Reputation: 310950

For starters it is better to declare the function like

char * Reverse( char *ptr );
^^^^^^

because standard C string functions usually return pointers to destination strings.

The function should reverse the original string. It may not create a dynamic string because the caller of the function will be unable to free it provided that the function has return type void.

The function can look as it is shown in the following demonstrative program.

#include <stdio.h>

char * Reverse( char *ptr )
{
    char *first = ptr, *last = ptr;

    while ( *last ) ++last;

    if ( first < last )
    {
        for ( ; first < --last; ++first  )
        {
            char c = *first;
            *first = *last;
            *last  = c;
        }
    }

    return ptr;
}

int main( void ) 
{
    char s[] = "Hello World!";

    puts( s );
    puts( Reverse( s ) );

    return 0;
}

Its output is

Hello World!
!dlroW olleH

Take into account that you may not call the function like

puts( Reverse( "Hello World!" ) );

because string literals are immutable in C.

If you are going to declare the function like

void Reverse( char *ptr );

then just remove the return statement in the shown function. For example

#include <stdio.h>

void Reverse( char *ptr )
{
    char *first = ptr, *last = ptr;

    while ( *last ) ++last;

    if ( first < last )
    {
        for ( ; first < --last; ++first  )
        {
            char c = *first;
            *first = *last;
            *last  = c;
        }
    }
}

int main( void ) 
{
    char s[] = "Hello World!";

    puts( s );
    Reverse( s )
    puts( s );

    return 0;
}

If to use your approach with indices then the function can look like

#include <stdio.h>

void Reverse( char *ptr ) 
{
    size_t size = 0;

    while ( *( ptr + size ) ) ++size;

    if ( size != 0 )
    {
        for ( size_t left = 0, right = size - 1; left < right; left++, right-- ) 
        {
            char c     = ptr[left];    // or char c = *( ptr + left ); and so on
            ptr[left]  = ptr[right];
            ptr[right] = c;
        }           
    }
}

int main( void ) 
{
    char s[] = "Hello World!";

    puts( s );
    Reverse( s );
    puts( s );

    return 0;
}

Upvotes: 4

chqrlie
chqrlie

Reputation: 144695

You have several problems in your code:

  • you do not allocate enough space for the resulting string, you must allocate size+1 bytes and set the \0 terminator at the end of the string.
  • you only copy half the characters from ptr to newString.
  • you are not even supposed to allocate memory, since you cannot call any library functions. You should instead reverse the string in place.
  • Your test fails because modifying a string literal invokes undefined behavior. You should pass an initialized array as shown below.

Here is an improved version:

#include <stdio.h>

void Reverse(char *ptr) {
    unsigned int left, right;

    for (right = 0; *(ptr + right) != '\0'; right++) {
         continue;
    }

    for (left = 0; left < right; left++, right--) {
        char ch = ptr[left];
        ptr[left] = ptr[right - 1];
        ptr[right - 1] = ch;
    }
}

int main(void) {
    char buf[] = "Hello world";
    Reverse(buf);
    printf("%s\n", buf);
    return 0;
}

It should print dlrow olleH.

Upvotes: 1

davek
davek

Reputation: 518

In your loop to get the size, you're not counting the null terminator. So your newString is missing the null terminator as well. make sure to do newString = malloc(size + 1);, and to place the null terminator onto the end of newString.

Upvotes: 1

Related Questions