用strtok()拆分字符串会出错

时间:2014-01-03 18:30:30

标签: c malloc clang realloc strtok

我正在尝试从用户那里获取输入,同时动态分配它,然后使用strtok“拆分”它。

主要问题:

  1. 我得到一个无限循环“a {\ 300_ \ 377”和“,”。
  2. 为什么我会收到“隐式声明库函数”的警告“malloc”/“realoc”类型为void“
  3. 其他不太重要的问题:

    3.i想要破解,如果输入包含“-1”,我该如何检查?正如你所看到的,如果它是1,它就会破裂。

    4.在getsWordsArray()中,我想返回一个指向字符串数组的指针。由于我不知道有多少字符串,我还需要像在getInput()中一样动态分配它。 (我不知道每个字符串中有多少个字符)

       int main(int argc, const char * argv[])
        {
            char input = getInput();
             getWordsArray(&input);  
        }
        char getInput()
        {   
            char *data,*temp;
            data=malloc(sizeof(char));
            char c; /* c is the current character */
            int i; /* i is the counter */
            printf ("\n Enter chars and to finish push new line:\n");
            for (i=0;;i++) {
                c=getchar(); /* put input character into c */
                if (c== '1')                // need to find a way to change it to -1
                    break;
                data[i]=c; /* put the character into the data array */
                temp=realloc(data,(i+1)*sizeof(char)); /* give the pointer some memory */
                if ( temp != NULL ) {
                    data=temp;
                } else {
                    free(data);
                    printf("Error allocating memory!\n");
                    return 0 ;
                }
            }   
            printf("list is: %s\n",data); // for checking
            return *data;     
        }
    
        void getWordsArray(char *input)
        {
            char *token;
            char *search = " ,";
            token = strtok (input,search);
            while (token != NULL ) {
                printf("%s\n",token);
                token = strtok(NULL,search);
            }
        }
    

    修改 我注意到我忘记了“strtok”命令所以我把它改为token = strtok(NULL,search);

    我仍然在printf上获得了很好的输出:

    \327{\300_\377
    

3 个答案:

答案 0 :(得分:2)

变化:

int main(int argc, const char * argv[])
{
    char input = getInput();
    getWordsArray(&input);  
}

为:

int main(int argc, const char * argv[])
{
    char *input = getInput();
    getWordsArray(input);  
}

getInput()的返回值类似:

char *getInput()
{   
    // ...
    return data;
}

在您的代码中,您只保存输入字符串的第一个字符,然后将大部分垃圾传递给getWordsArray()

对于您的malloc()问题,man malloc以:

开头
SYNOPSIS
   #include <stdlib.h>

对于您的getchar()问题,请参阅I'm trying to understand getchar() != EOF

答案 1 :(得分:2)

约瑟夫回答了Q1。

Q2:mallocrealoc返回void *类型。您需要将其显式转换为char *。试试这个:

data = (char *) malloc(sizeof(char));

Q3:1可以解释为一个字符。 -1,转换为字符时,相当于字符串“-1”,其字符为“ - ”和“1”。为了检查-1,您需要使用strcmpstrncmp来比较字符串“-1”。

问题4:如果你要返回另一个副本,是的,动态分配内存是个好主意。或者,您可以将每个标记的所有指针放入数据结构中,如链接列表,以供将来参考。这样,您就可以避免复制,只允许访问字符串中的每个标记。

答案 2 :(得分:1)

错误的事情:

  1. C中的字符串以空值终止。 %s的{​​{1}}参数表示“只需保持打印字符,直到您点击printf”。由于在打印之前没有空终止'\0'data正在printf的末尾运行,只打印堆(碰巧不包含任何空字节来阻止它) )。

  2. data的标题是什么?缺少#include是隐含声明<stdlib.h>的最明显原因。

  3. malloc按值返回getInput的{​​{1}}。这不是你想要的。 (char永远不会奏效。另见1.)

  4. 建议:

    这是打破-1的一个想法:data

    要获得字符串数组,您确实需要一个getWordsArray的动态数组。您可以if ((c == '1') && (data[i-1] == '-'))新的字符串来复制char *返回的每个malloc,或者只是将每个token直接保存为strtok的指针。