【问题标题】:How to split a string into words?如何将字符串拆分为单词?
【发布时间】:2018-08-09 14:56:06
【问题描述】:

我正在尝试将字符串拆分为单词。谁能帮我解决如何在不使用strtokmain 以外的其他功能的情况下实现它?

void main()
{
    int i;
    int myargc = 1;
    char *myargv[256];
    char buff[100];
    int len = 0;
    char string[256];
    int j = 0;

    printf("Enter text: ");
    gets(buff);

    for(i = 0; buff[i] != '\0'; i++){
        len++;
    }

    for(i = 0; i < len; i++)
    {
        if(buff[i]!=' ' && buff[i+1]==' ')
        {
            myargc++;
        }
    }
    printf("myargc %d\n",myargc);

    **for(i = 0; i < len; i++){
        if(buff[i] != ' '){
            string[j++] = buff[i];
        }
        if(buff[i] != ' ' && buff[i] == ' '){
            string[j++] = '\0';
            j = 0;
        }
        if(buff[i] == '\0'){
            break;
        }
    }**
    for(i = 0; i < myargc - 1; i++){
        myargv[i] = string;
        printf("argv[%d]\t%s\n", i, myargv[i]);
    }
}

例如,当我输入“a b c”时,我的输出如下所示:

myargc 3
argv[0] abc
argv[1] abc
argv[2] abc

【问题讨论】:

  • 您没有为myargv[] 中的指针分配任何内存或复制任何字符串 - 您只是在分配指针。
  • myargv[] 的每个元素都指向内容不断变化的string[]。所以它们都指向同一个东西,最后处理的字符串。
  • @PaulR 将 buff[i] == ' ' 分配给 buff[i] = '\0' 然后执行字符串复制是否正确?
  • 听起来您可能需要学习如何使用debugger 来单步执行您的代码。使用好的调试器,您可以逐行执行您的程序,并查看它与您期望的偏差在哪里。如果您要进行任何编程,这是必不可少的工具。进一步阅读:How to debug small programs.

标签: c arrays string argv argc


【解决方案1】:

所以这是我的解决方案,不确定它是否是最佳的,但也适用于单词之间的更多空格。

#include <stdio.h>
#include <stdlib.h>

void main()
{
    int i;
    int myargc = 1;
    char **myargv;
    char buff[100];
    int len = 0;
    char string[256];
    int j = 0, k =0;

    printf("Enter text: ");
    gets(buff);

    for(i = 0; buff[i] != '\0'; i++){
        len++;
    }

    for(i = 0; i < len; i++)
    {
        if(buff[i]!=' ' && buff[i+1]==' ')
        {
            myargc++;
        }
    }
    printf("myargc %d\n",myargc);

    //allocating 256 bytes * number of words    
    myargv = (char**)malloc(myargc*sizeof(char*));
    for(i = 0; i < myargc; i++){
        myargv[i] = (char*)malloc(256*sizeof(char));
    }

    //iterating until the ending character
    for(i = 0; i <= len; i++){
        //building word
        if(buff[i] != ' ' && buff[i] != 0)
        {   
            string[j++] = buff[i];
        }

        //copying word to corresponding array
        else if((buff[i] == ' ' && buff[i+1] != ' ') || (buff[i] == 0))
        {
            for(int z = 0; z < j; z++){
                myargv[k][z] = string[z];
            }

            myargv[k++][j] = '\0';
            j = 0;
        }

        //skipping more spaces in a row
        else continue;
    }


    for(i = 0; i < myargc; i++){
        printf("argv[%d]\t%s\n", i, myargv[i]);
    }

    }

【讨论】:

  • 感谢您的帮助。我想问一下 char **myargv 和 char *myargv[256] 有什么区别。我试图搜索它,但我找不到关于它们的区别的更详细的解释。
  • 查看此网站:cdecl.org。因此,根据您的声明,您将 myargv 声明为一个包含 256 个指向 char 的指针的数组。在您不知道会得到多少单词的情况下,我认为动态分配是节省内存的好方法。起初,您分配的 char 指针与字数一样多。第二步是 forloop,对于每个指向 char 的指针,您需要分配一些内存来存储字符串。这就是为什么声明中有两颗星。
  • 我认为问题不在于您对 myargv 的声明,而在于拆分原始字符串。在您突出显示的 forloop 中,您只是删除了空格,第二个条件从未执行过,因为如果条件的第一部分为真,则第二部分不能为真。在最后一个 forloop 中,您的连接字符串被分配给数组中的每个指针,因此输出仍然相同。
猜你喜欢
  • 2011-06-12
  • 2011-04-22
  • 2023-01-22
  • 2014-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多