c - 指针算术问题 - 尝试对输入字符串进行标记

标签 c string pointers tokenize pointer-arithmetic

目前我正在开发一个程序,该程序允许用户输入一个字符串,然后将其标记化,然后使用指针数组将标记打印到屏幕上。 “应该”通过调用我的 tokenize 函数来执行此操作,该函数读取输入字符串直到第一个分隔符(“”、“、”、“.”、“?”、“!”)。然后它将字符串中的分隔符更改为 NULL 字符。然后它应该返回一个指向字符串中下一个字符的指针。 在 main 中输入字符串后,它应该继续调用 tokenize 函数,该函数返回指针,然后将这些指针存储在指针数组中以便稍后打印我的 token 。一旦 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.当我编译时,它读取字符串然后打印它,然后陷入无限循环,没有任何打印,仍然试图获取输入。 2. 我很确定我在错误的地方使用了“*”作为我的指针。 3.我的函数传入了对我的数组的引用,因此我假设我可以按原样增加它们。

感谢任何反馈!我会经常关注这篇文章。如果我留下不清楚的地方,我可以重新指定。谢谢。

最佳答案

您对于解决问题的想法是正确的,但整个代码中存在大量 pointer/int 错误。确保在启用警告的情况下编译代码,这会告诉您代码中存在问题的位置。 (在解决并消除所有警告之前,不要指望您的代码能够正确运行)。至少,在构建命令中使用 -Wall -Wextra 选项进行编译。

有很多更简单的方法可以做到这一点,但对于学习体验来说,这是一个很好的练习。以下是已更正错误的代码。在可能的情况下,我已对您的原始代码进行了注释,以便您可以看到问题出在哪里。我还添加了一些代码来删除 fgetstext 末尾包含的 newline。虽然这不是必需的,但最好不要在代码中过滤杂散的换行符

如果您有疑问,请告诉我:

#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

关于c - 指针算术问题 - 尝试对输入字符串进行标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27216166/

相关文章:

Java - 给定正则表达式的所有子字符串

c++ - 如何将给定的字行输入到以空格分隔的不同字符串中?

c++ - 如何使用指针从不同的函数访问局部变量?

c++ - 如何获取字符串指针的值?

c - 我的这个推理哪里错了?

c - 尝试将字符串转换为整数数组的艰难时期

c# - 将 HtmlAgilityPack.HtmlNode 转换为字符串

c - 需要了解一个用输出覆盖输入的简单示例

c - Makefile "makefile"中的 "kaodv.o: $(KOBJS) Makefile"是什么意思

c - 2>&1 对 popen 做了什么?