简体   繁体   中英

Reverse a string without strtok in C

Working on a program that uses RPN (Reverse Polish Notation).

I have a function that reverses all the words of string without using strtok or triggering printf (unlike all the solutions found online and here).

The function actually works partially as it prints all the words of a given string except the last one and I need help figuring out what's going on.

char *extract(char s[]) {
    if (s[0] == '\0') 
        return NULL;
    int i = 0;
    char *p = NULL;
    while (s[i] != '\0') {
        if (s[i] == ' ')
            p = s + i;
        i++;
    }
    if (p != NULL) {
        *p = '\0';
        return p + 1;
    }
}

And then it's called in main like this:

char s[MAX] = "5 60 +";
while(s != NULL){
    printf("%s\n", extract(s));
}

The output is + 60 with the cursor endessly waiting for something but the expected output should be + 60 5

A standard approach is to reverse each word within a string and then to reverse the whole string.

Here you are.

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

static char * reverse( char *s, size_t n )
{
    for ( size_t i = 0; i < n / 2; i++ )
    {
        char c = s[ i ];
        s[ i ] = s[ n - i - 1 ];
        s[ n - i - 1 ] = c;
    }

    return s;
}

char * reverse_by_words( char *s )
{
    const char *delim = " \t";

    char *p = s;

    while ( *p )
    {
        p += strspn( p, delim );

        if ( *p )
        {
            char *q = p;

            p += strcspn( p, delim );

            reverse( q, p - q );
        }
    }

    return reverse( s, p - s );
}

int main(void) 
{
    char s[] = "5 60 +";

    puts( s );

    puts( reverse_by_words( s ) );

    return 0;
}

The program output is

5 60 +
+ 60 5

If you want to keep leading and trailing spaces as they were in the original string then the functions can look the following way

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

static char *reverse( char *s, size_t n )
{
    for ( size_t i = 0; i < n / 2; i++ )
    {
        char c = s[i];
        s[i] = s[n - i -1 ];
        s[n - i - 1] = c;
    }

    return s;
}

char * reverse_by_words( char *s )
{
    const char *delim = " \t";

    char *first = s, *last = s;

    for ( char *p = s;  *p; )
    {
        p += strspn( p, delim );

        if ( last == s ) first = last = p;


        if ( *p )
        {
            char *q = p;

            p += strcspn( p, delim );

            last = p;

            reverse( q, p - q );
        }
    }

    reverse( first, last - first );

    return s;
}

int main(void) 
{
    char s[] = "\t\t\t5 60 +";

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

    printf( "\"%s\"\n", reverse_by_words( s ) );

    return 0;
}

The program output is

"           5 60 +"
"           + 60 5"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM