【问题标题】:Splitting a string with strtok() goes wrong用 strtok() 拆分字符串出错
【发布时间】:2014-01-21 12:30:07
【问题描述】:

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

主要问题:

  1. 我遇到了“a{\300_\377”和“,”的无限循环。
  2. 为什么我会收到“隐式声明库函数“malloc”/“realoc”类型为 void”的警告

其他不太重要的问题:

3.我想打破,如果输入包括“-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

【问题讨论】:

  • 什么是'token = (NULL,search);'
  • 糟糕.. 已编辑,谢谢。

标签: c malloc clang realloc strtok


【解决方案1】:

变化:

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 等。

【讨论】:

    【解决方案2】:

    约瑟夫回答了 Q1。

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

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

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

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

    【讨论】:

    • R.e. data = (char *) malloc(sizeof(char))。强制转换在 C++ 中是必要的,但在 C 中是不必要的,而且确实不受欢迎。
    • @JosephQuinsey 这就是为什么我认为即使在 C 中进行这种显式类型转换也是一种很好的做法。尽管在 C++ 中,这也已被弃用,因此除非绝对必要,否则应避免这种情况,即重用巨大的一大块 C 代码。
    【解决方案3】:

    错误的地方:

    1. C 中的字符串以空值结尾。 printf%s 参数的意思是“继续打印字符,直到你遇到 '\0'”。由于您在打印之前没有对 data 进行空终止,因此 printf 将在 data 的末尾运行并仅打印您的堆(恰好不包含任何空字节来停止它)。

    2. #include 使用了哪些标题?缺少&lt;stdlib.h&gt; 是隐式声明malloc 的最明显原因。

    3. getInput 按值返回data 的第一个char。这不是你想要的。 (getWordsArray 永远不会工作。另请参阅 1。)

    建议:

    这是打破 -1 的一个想法:if ((c == '1') &amp;&amp; (data[i-1] == '-'))

    要获取字符串数组,您确实需要char * 的动态数组。您可以malloc 一个新字符串来复制strtok 返回的每个token,或者直接将每个token 保存为指向input 的指针。

    【讨论】:

    • 谢谢,但我没有得到关于 printf 的第一件事 - 你有什么建议?
    • @YevgeniTarler 跳出循环后,您需要在data 的末尾再添加一个元素并将其设置为'\0'。然后你的 char 数组就变成了一个有效的以空字符结尾的字符串。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-05
    • 2014-07-27
    相关资源
    最近更新 更多