0

Currently I am working on a program that allows a user to enter a string that is then tokenized, then the tokens are printed to the screen by using an array of pointers. It is "supposed" to do this by calling my tokenize function which reads the input string until the first separator ( ' ', ',', '.', '?', '!'). It then changes that separator in my string to a NULL char. It then should return a pointer to the next character in my string. In main after the string has been input, it should keep calling the tokenize function which returns pointers which are then stored in a array of pointers to later print my tokens. Once the tokenize() returns a pointer to a NULL character which is at the end of my string it breaks from that loop. Then I print the tokens out using my array of pointers. //trying to be detailed

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

char *tokenize ( char *text, const char *separators );

int main ( void )
{
        char text[30];
        char separators[6] = { ' ','.',',','?','!','\0'};
        char *pch = NULL;
        int tokens[15];
        int i = 0;
        int j = 0;

        printf("Enter a string: \n");
        fgets( text, 30, stdin );

        printf("%s", text );

        pch = tokenize ( text, separators );

        do
        {
                pch = tokenize ( pch, separators );
                //printf("%c", *pch);
                tokens[i] = pch;
                i++;
        }
        while( *pch != NULL );


        i--;
        while( j != i )
        {
                printf("%s", tokens[i] );
                j++;
        }

        return 0;
}

char *tokenize ( char *text, const char *separators )
{
        while( text != NULL )
        {

                if( text != NULL )
                {
                        while( separators != NULL )
                        {
                                if( text == separators )
                                {
                                        text = '\0';
                                }
                                separators++;
                        }
                }
                text++;
        }
        return text;


}

3 big known problems currently. 1.When I compile, it reads the string then prints it, then gets stuck in a endless loop with nothing printing, still trying to get input. 2. Im pretty sure I am using the " * " for my pointers in the wrong place. 3. My function passes in a reference to my arrays, so I assumed i could just increment them as is.

I appreciate any feedback! I will be watching this post constantly. If i left something unclear, I can respecify. Thanks.

St-rm
  • 13
  • 4
  • Are you trying to reimplement `strtok`? – n. m. could be an AI Nov 30 '14 at 17:53
  • Please take a look at strspn() and strcspn() – wildplasser Nov 30 '14 at 17:53
  • `pch = tokenize ( text, separators );` 1st argument must be updated. – BLUEPIXY Nov 30 '14 at 18:07
  • i looked at strtok and that is exactly what Im doing, except I cant have any libray functions except the ones Im currently using. @BLUEPIXY (oh crap i cant believe i missed that) and another really concerning issue is when i do `tokens[i] = pch;`. Am i storing the pointer? – St-rm Nov 30 '14 at 18:17
  • 1
    `tokenize` return the same result because `tokenize` is always receive the same argument. e.g. `char *p = text;` .. `tokenize(&p, separators);` `p` update by `tokenize`. `tokenize` can process continues. – BLUEPIXY Nov 30 '14 at 18:25
  • kinda confused about what you just posted. but I think i corrected for this error now back in my original post by doing a function call before i go into my while loop. but when i run it, nothing has changed. @BLUEPIXY – St-rm Nov 30 '14 at 18:31
  • Processing the contents of the `tokenize` is wrong. and also `pch = tokenize ( pch, separators );` same thing if return top of `text` as `pch`. – BLUEPIXY Nov 30 '14 at 18:39
  • this line: while( text != NULL ) is comparing a pointer to NULL what actually needs to be done is compare the char where text points to '\0' suggest: while( *text != '\0' ) Similar considerations for this line: while( separators != NULL ) – user3629249 Dec 01 '14 at 02:24
  • this line: int tokens[15]; is defining an array of int. However, pointers to char are being stored, so the line should be: char * tokens[15]; – user3629249 Dec 01 '14 at 02:27

2 Answers2

0

Maybe you will want to take a look at strsep and this post Split string with delimiters in C If you need more reference points try searching "split string" it is what you want to do if I understood correctly.

Community
  • 1
  • 1
Tchou
  • 60
  • 6
0

You had right idea for approaching the problem, but you had numerous pointer/int errors throughout your code. Make sure you compile your code with Warnings enabled, this will tell you where you have problems in your code. (don't expect your code to run correctly until you address and eliminate all warnings). At a minimum, compile with -Wall -Wextra options in your build command.

There are a lot easier ways to do this, but for the learning experience, this is a great exercise. Below is your code with the errors corrected. Where possible, I have left your original code commented so you can see where the issues were. I also include a bit of code to remove the newline included by fgets at the end of text. While this isn't required, it is good practice not to have stray newlines filter through your code.

Let me know if you have questions:

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

char *tokenize ( char *text, const char *separators );

int main ( void )
{
        char text[30];
        char separators[6] = { ' ','.',',','?','!','\0'};
        char *pch = NULL;
        char *tokens[15] = {0};             /* declare array of pointers    */
        int i = 0;
        int j = 0;

        printf("Enter a string: \n");
        fgets( text, 30, stdin );
        size_t len = strlen (text);

        if (text[len-1] == '\n')            /* strip newline from text      */
            text[--len] = 0;

        pch = text;                         /* pch pointer to next string   */
        char *str = text;                   /* str pointer to current       */

        do
        {
                pch = tokenize ( str, separators ); /* pch points to next   */
                tokens[i++] = str;                  /* save ptr to token    */
                str = pch;                          /* new start of str     */
        }
        while (pch != NULL && *pch != 0);           /* test both pch & *pch */

        printf ("\nTokens collected:\n\n");
        while (tokens[j])                   /* print each token             */
        {
                printf("  token[%d]: %s\n", j, tokens[j] );
                j++;
        }
        printf ("\n");

        return 0;
}

char *tokenize ( char *text, const char *separators )
{
        const char *s = separators;     /* must use pointer to allow reset  */

        //while( text != NULL )
        while( *text != '\0' )
        {
                s = separators;         /* reset s                          */
                while( *s != 0 )        /* 0 is the same as '\0'            */
                {
                        //if( text == separators )
                        if( *text == *s )
                        {
                                //text = '\0';
                                *text = '\0';
                                return ++text;
                        }
                        s++;
                }
                text++;
        }
        return text;
}

Example output:

$ ./bin/tokenizestr
Enter a string:
This is a test string

Tokens collected:

  token[0]: This
  token[1]: is
  token[2]: a
  token[3]: test
  token[4]: string
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Thank you so much @David C. Rankin . super glad you posted this, and I understand my mistakes. I really appreciate it. – St-rm Dec 01 '14 at 18:24