指针算术的问题 - 尝试标记输入字符串

时间:2014-11-30 17:39:42

标签: c string pointers tokenize pointer-arithmetic

目前我正在开发一个程序,允许用户输入一个字符串然后进行标记化,然后使用指针数组将标记打印到屏幕上。它应该通过调用我的tokenize函数来执行此操作,该函数读取输入字符串直到第一个分隔符('',',','。','?','!')。然后它将我的字符串中的分隔符更改为NULL char。然后它应该返回一个指向我的字符串中的下一个字符的指针。 在输入字符串之后的main中,它应该继续调用tokenize函数,该函数返回指针,然后存储在指针数组中以便稍后打印我的标记。一旦tokenize()返回一个指向NULL字符的指针,该字符位于我的字符串的末尾,它就会从该循环中断开。然后我使用我的指针数组打印出令牌。 //试图详细

#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大问题。 1.当我编译时,它读取字符串然后打印它,然后陷入无限循环,没有任何打印,仍然试图获得输入。 我很确定我在错误的地方用我的指针“*”。 3.我的函数传递了对我的数组的引用,所以我假设我可以按原样递增它们。

我感谢任何反馈!我会不断看这篇文章。如果我留下一些不清楚的东西,我可以重新指定。感谢。

2 个答案:

答案 0 :(得分:0)

也许你会想看看 strsep和此帖子Split string with delimiters in C 如果您需要更多参考点,请尝试搜索“拆分字符串”,如果我理解正确,您就应该这样做。

答案 1 :(得分:0)

您有正确的想法来解决问题,但您的代码中有很多pointer/int错误。确保使用启用警告编译代码,这将告诉您代码中的问题所在。 (在您解决并消除所有警告之前,不要指望您的代码能够正确运行)。至少,在构建命令中使用-Wall -Wextra选项进行编译。

有很多简单的方法可以做到这一点,但对于学习体验,这是一个很好的练习。以下是纠正错误的代码。在可能的情况下,我保留了原始代码commented,以便您可以查看问题所在。我还添加了一些代码,用于删除newline末尾的fgets所包含的text。虽然这不是必需的,但最好不要对代码进行过度newlines过滤。

如果您有任何疑问,请与我们联系:

#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;
}

示例输出:

$ ./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