max
max

Reputation: 167

To return the ith word in the string

Implement char * ithword(char * str, int i) that will return the ith word in str. The words are alphanumeric and separated by non-alphanumeric characters. The function will allocate memory for the word returned, and return a pointer to it.

My code:

char *ithword(char * str, int i)
{   
    /* declarations */
    char *der = malloc(100 * sizeof(int));
    int nw, state, j, counter;
    state = 0;
    nw = 0;
    counter =0 ;

    for(j = 0; (nw <= i) || (j < sizeof(str)); j++) { 
        char c = str[j];
        if (c == '\0')
            return der;
        if (isalnum(c) == 0) {
            state = 0;
            continue;
        }
        if (state == 0) {            
            state = 1;
            nw++;
        }
        if (nw == i) {
            der[counter]=c;
            counter++;
        }
    }
    return der;
}
int main()
{
    char *p = malloc(101);
    p = ithword("bcd&acd*abc",3);
    printf("%s",p); 
}

Upvotes: 0

Views: 233

Answers (2)

tdao
tdao

Reputation: 17668

It may be resolved by strtok as well:

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

int main()
{
    char str[] = "To !@ return #$ the ith word in the string";
    char *p = str;
    char *pch;
    for( ; *p; p++ )        // replace all non-alpha characters with single space.
    {
        if (!isalpha(*p)) *p = ' ';
    }

    int i_th = 5;           // the ith word to expect.
    pch = strtok(str, " "); // first word.
    int i = 1;
    while( pch != NULL )
    {
        i++;
        pch = strtok (NULL, " ");
        if( i == i_th )
        {
            break;
        }
    }

    printf( "the %dth word is \"%s\"\n", i_th, pch );
}

Output:

the 5th word is "word"

Upvotes: 1

thepace
thepace

Reputation: 2221

Some issue that I see, I have added comments.

char *ithword(char * str, int i)
{
    char *der = (char *)malloc(101); # Why sizeof(int) when it has to store characters.
    memset(der ,0, 101); # Always memset a malloc allocated memory else garbage value would be printed.
    int nw, state, j, counter;
    state = 0;
    nw = 0;
    counter =0 ;

    for(j = 0; (nw <= i) || (j < sizeof(str)); j++) { 
        char c = str[j];
        if (c == '\0')
            return der;
        if (isalnum(c) == 0) {
            state = 0;
            continue;
        }
        if (state == 0) {            
            state = 1;
            nw++;
        }
        if (nw == i) {
            der[counter]=c;
            counter++;
        }
    }
    der[counter] = '\0'; # The output string has to be null terminated else all the characters would be printed from the memory location until a null is encountered.
    return der;
}

int main()
{
    char *p = NULL; # Do not allocate here. What you did would create dangling pointer because you have allocated it and then pointed it to some other location.
    p = ithword("bcd&acd*abc",3);
    printf("%s",p);
    return 0; # Return an exit code (0) since it has to return an int.
}

Pointing out the issues again:

  • Dangling pointers in main().
  • Prefer returning an exit code from main() as per the definition.
  • Always memset a memory if its allocated via malloc else it would have garbage value which could lead to uncertain output.
  • Always null terminate a self-created string because while printing the compiler prints all the characters until '\0' is encountered.
  • Suggestion: Instead of blindly allocating 101, find input string str's length and allocate that size so that it can take care of small and big strings.

Upvotes: 1

Related Questions