实现'split'函数时c代码输出不一致

qacovj5a  于 2023-10-16  发布在  其他
关注(0)|答案(2)|浏览(85)

我试图在C中实现python中的'split()'函数,并使用以下代码:

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

int strsplit(char *, unsigned long *);
void strprint(char *);
void empty_arr(char *);

int main()
{

  char str1[] = "help me out"; // changeable line ~~~~~~~~~~~~~~
  unsigned long str2[strlen(str1)];

  int k = strsplit(&str1, &str2);
  unsigned long *p;
  p = &str2;

  for (int i = 0; i < k; i++)
  {
    printf("%u\n", str2[i]);
  }

  return 0;
}

void strprint(char *s)
{
  while (*s != '\0')
  {
    printf("%c\n", *s);
    s++;
  }
}

void empty_arr(char *a)
{
  while (*a != '\0')
  {
    *a = '\0';
    a++;
  }
}

int strsplit(char *s, unsigned long *n)
{

  int i = 0;
  char temp[50];
  char *t = temp;

  while (1 == 1)
  {
    // printf("*s = %c\n", *s);
    // printf("Length: %u\n\n", strlen(temp));

    if (*s == ' ' || *s == '\0')
    {
      // printf("Entering!\n");
      *n = strlen(temp);
      n++;
      i++;
      empty_arr(temp);
      t = &temp;
      if (*s == '\0')
        break;
    }
    else
    {
      *t = *s;
      t++;
    }

    s++;
  }
  return i;
}

输出为:4 2 3 3
但是,当我将str1(注解为“changable line”)更改为“help me out man”时,我收到的输出是这样的:6 2 3 3
对于第一个输入,函数strsplit正确地将单词“help”的长度确定为4,但是对于第二个输入,它将其确定为6。
我用高级语言编程,但从未用过像C这样的低级语言。任何帮助将不胜感激。

gijlo24d

gijlo24d1#

注意到的一些问题:

  • int k = strsplit(&str1, &str2);应该是int k = strsplit(str1, str2);
  • t = &temp;应为t = temp;
  • p = &str2;应该是p = str2;-但p没有使用,所以只需删除它。
  • 打印unsigned long s不应该使用%u,而是%lu
  • 你可能应该初始化temp,以防测试字符串以空格或\0开头,因为如果它这样做了,你将在一个未初始化的字符串上执行strlen,结果是 undefined behavior

有了这些修改,以及输入"help me out man",程序将打印:

4
2
3
3
vq8itlhq

vq8itlhq2#

当C标准库已经提供了你想要的功能时,为什么还要尝试编写代码呢?如果你熟悉Python,那么你应该知道库的存在。

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

int main() {
    char buf[] = "Once upon a time there lived a beautiful princess.", *p = buf;
    char **t = NULL; size_t sz = sizeof *t;
    int n = 0;

    while(!!(t=realloc(t,(n+1)*sz))&&!!(t[n]=strtok(p," .\n"))) p=NULL, n++;

    for( int i = 0; i < n; i++ )
        puts( t[i] );

    free( t );

    return 0;
}

一个单一的紧密while()循环将输入字符串分割成分隔符(如Python的split()),将指向每个段的指针存储到一个不断增长的已分配动态数组中。
测试结果:

Once
upon
a
time
there
lived
a
beautiful
princess

在浪费时间重新发明轮子之前,先了解哪些是可用的和经过验证的。
(Note:假定了一个 mutable 字符串,并且在此示例代码中没有报告realloc()可能的失败。)

编辑

有一些关于上面代码的 * 密度 * 的评论。下面是等效代码(具有管理realloc()故障的好处)。

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

int main() {
    char buf[] = "Once upon a time there lived a beautiful princess.";
    char *cp = buf;

    char **arr = NULL;
    int n = 0;

    for( ;; )
    {
        cp = strtok( cp, " .\n" );
        if( cp == NULL )
        {
            break;
        }

        char **tmp = realloc( arr, (n+1) * sizeof *tmp );
        if( tmp == NULL )
        {
            perror( "realloc" );
            free( arr ); // release what may have been acquired.
            exit( EXIT_FAILURE );
        }
        arr = tmp;

        arr[ n++ ] = cp;
        cp = NULL;
    }

    for( int i = 0; i < n; i++ )
        puts( arr[i] );

    free( arr );

    return 0;
}

相关问题