C中的手动分割功能

时间:2011-05-17 20:35:50

标签: c split

这段代码让我起了作用。目标是基于逗号分割为char []。它适用于java。但是在C中打印出奇怪的输出。我怀疑在循环的第二次迭代中出现错误,我尝试添加5个数组变成奇怪的字符。

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

main()
{
    char asshat[] = {'4','5','5',',','7','4','7','\0'};

    int firstSize = 0;//
    int secondSize = 0;//

    //new = 4 \0 \0
    char first[] = {'0', '\0'};//
    //new = 
    char second[] = {'0', '\0'};//
    char *first_ptr = first;
    char *second_ptr = second;

    int takingFirst = 1;
    int takingSecond = 0;

    int i;
    for (i = 0; i < strlen(asshat); i++)
    {
        if (asshat[i] != ',')
        {
            if (takingFirst == 1)
            {
                first_ptr[firstSize] = asshat[i];//ERROR here when you add 5 you s**t bricks
                firstSize++;
                if (asshat[i+1] != ',')
                {
                    char new[firstSize+2];
                    int k;
                    for (k = 0; k < strlen(first_ptr); k++)
                    {
                        new[k] = first_ptr[k];
                    }
                    new[firstSize] = '0';
                    new[firstSize+1] = '\0';
                    first_ptr = new;
                }
            }
            if (takingSecond == 1)
            {
                second_ptr[secondSize] = asshat[i];
                secondSize++;
                if (asshat[i+1] != '\0')
                {
                    char new[secondSize+2];
                    int k;
                    for (k = 0; k < strlen(second_ptr); k++)
                    {
                        new[k] = second_ptr[k];
                    }
                    new[secondSize+1] = '\0';
                    second_ptr = new;
                }
            }
        }
        else
        {
            takingFirst = 0;
            takingSecond = 1;
        }
    }
    printf("%d\n",strlen(first_ptr));
    printf("%c%c%c\n",first_ptr[0],first_ptr[1],first_ptr[2]);
    printf("%s\n",first_ptr);

    printf("%d\n",strlen(second_ptr));
    printf("%c%c%c\n",second_ptr[0],second_ptr[1],second_ptr[2]);
    printf("%s\n",second_ptr);
}

5 个答案:

答案 0 :(得分:2)

您将new声明为局部变量,并让first_ptr指向该局部变量的内存位置:

{
    char new[firstSize+2];
    ...  
    first_ptr = new;
}

然后局部变量超出范围,其内存将被未来创建的其他变量/ ...重用。 first_ptr仍然指向该内存位置,但那里的数组不再存在。当尝试通过first_ptr访问数组时,可能会发生任何事情,您很可能会发现意外的值。

答案 1 :(得分:0)

很难读懂您的解决方案正在做什么。我尝试在保持指针播放的同时重新实现它更简单:

#include <stdio.h>

int 
main(int argc, char *argv[])
{   
  /* Keeping variable names consistent :) */
  char asshat[] = "456,747";
  char *first = asshat, *second = asshat, *c = asshat;

  while (*c) {
    if (*c == ',') {
      *c = '\0'; second = ++c;
    } else c++;
  }   
  printf("first: %s\nsecond: %s\n", first, second);
  return 0;
}   

这会产生:

first: 456
second: 747

答案 2 :(得分:0)

你可以用大致一行切片来做到这一点:)

假设至少有一个, ...

char asshat[] = "hello,world";
char* second = asshat;
while (*second++ != ',');
*(second - 1) = 0;

printf("first: %s; second: %s\n",asshat,second);

你可以在此基础上检查是否有逗号(如果没有逗号会崩溃)。

答案 3 :(得分:0)

要在C中拆分字符串,我建议你留下strtok()的辛苦工作。如果你不需要,不要重新发明轮子。

答案 4 :(得分:0)

我假设您要将“455”复制到first而将“747”复制到second?如果是这样,你没有为此分配足够的空间。 char first[] = {'0', '\0'}仅分配一个大小为2的数组;你需要4. second相同。

您试图通过找出原始字符串中的位置来解决同一级别的太多问题,无论您是要复制到first还是{{ 1}} 跟踪每个子字符串的长度;这会导致您的困惑,并使问题变得更加困难。

首先分开关注点:您需要一个函数来查找输入中的下一个子字符串,另一个函数将该子字符串复制到其目标中。

坦率地说,分割字符串的最佳方法是使用标准库函数secondstrtokstrchr中的任何一个,并使用strcspnstrcpy将子字符串复制到目标数组。 使用strncpy有很多非常好的理由,但它是最简单的方法之一,可以帮助您完成所需的工作。

以下是使用strtok的一般程序:

strtok

正如我上面提到的,有想要使用char *token = strtok(asshat, ","); // return a pointer to the substring // before the first comma while (token) { strcpy(destination[i++], token); // assumes destination exists and is // large enough to hold the token contents token = strtok(NULL, ","); // find the next substring in the sequence; // pass NULL to indicate you're continuing // in the same string } 的原因。它修改输入字符串(用0替换分隔符),因此不能在字符串文字上使用它。您可能还想保留原始字符串。此外,strtok不是可重入的,也不是线程安全的。

将它应用于您的特定情况,您可以执行以下操作:

strtok