【问题标题】:Strtok using dynamic memoryStrtok 使用动态内存
【发布时间】:2015-03-24 19:23:23
【问题描述】:

我有以下代码,我需要帮助来获取和存储最后一个令牌。现在代码在每个空格之后都进行标记,但是当它到达我的文本文件的末尾时,它不会标记最后一个值。我很确定我需要在 malloc 语句之前有令牌,但是当我在前面添加它时,我得到了一个段错误。有人知道这个问题吗?上面初始化myStruct.extras = NULL是因为realloc;这是char **

token = strtok(fileArrayPTR[p],"X");
while (token!= NULL)
{   

    if (tempCounter == 0)
    { 
        token = strtok(NULL," "); 
        myStruct.dimensions[1] = strtol(token,&ptr,10);
    }else{
        myStruct.extras = realloc(myStruct.extras,(extraCounter + 1) * sizeof(char *)); 
        myStruct.extras[extraCounter] = malloc(strlen(token)+1);  
        strcpy(myStruct.extras[extraCounter],token);
        token = strtok(NULL," ");
        extraCounter++;
    }
}

编辑:忘记放置递增的计数器

【问题讨论】:

  • 你在哪里增加extraCounter
  • 对不起,忘记添加了。我在令牌后面有它
  • 发布更多循环的初始化。如果我们能看到原始字符串是如何被读入的,你至少是如何初始化 token 和 extraCounter 的,那就太好了。另外,myStruct.extras 是如何初始化的?
  • 如果您不给我们 MCVE (Minimal, Complete, Verifiable Example),我们很难调试您的代码。如果您创建了一个 MCVE,您可能会在开发它时很好地解决您的问题。如果做不到这一点,我们很容易看出问题出在哪里。另请参阅 SSCCE (Short, Self-Contained, Correct Example) — 一个替代但等效于 MCVE 的想法。
  • 所以你说它只是错过了输入文件中的最后一个标记?那么问题可能在于您如何阅读输入。正如乔纳森所说,您应该发布一个重现问题的最小示例;包括一个示例输入文件(希望在重现中只需要几行)。还要检查最后一行是否以换行符结尾以及换行符是否存在。

标签: c memory dynamic strtok


【解决方案1】:

这是问题中的代码(第二版):

token = strtok(fileArrayPTR[p],"X");
while (token!= NULL)
{   
    if (tempCounter == 0)
    { 
        token = strtok(NULL," "); 
        myStruct.dimensions[1] = strtol(token,&ptr,10);
    }else{
        myStruct.extras = realloc(myStruct.extras,(extraCounter + 1) * sizeof(char *)); 
        myStruct.extras[extraCounter] = malloc(strlen(token)+1);  
        strcpy(myStruct.extras[extraCounter],token);
        token = strtok(NULL," ");
        extraCounter++;
    }
}

这不是一个独立的程序。我们可以通过以下方式改进它:

  • 移除结构。
  • 显示相应的变量声明。
  • 将其转换为简单的main()

这些变化导致:

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

int main(void)
{
    int extraCounter = 0;
    char **extras = 0;
    int tempCounter = 0;
    char *ptr = 0;
    char data[] = "10X16 something another-thing";
    char *token = strtok(data, "X");
    int dimension1 = strtol(token, &ptr, 10);
    int dimension2 = -1;
    while (token!= NULL)
    {   
        if (tempCounter == 0)
        {
            token = strtok(NULL," "); 
            dimension2 = strtol(token, &ptr, 10);
            tempCounter++;
        }
        else
        {
            extras = realloc(extras, (extraCounter + 1) * sizeof(char *)); 
            extras[extraCounter] = malloc(strlen(token)+1);  
            strcpy(extras[extraCounter], token);
            token = strtok(NULL, " ");
            extraCounter++;
        }
    }

    printf("Dimensions: %dx%d\n", dimension1, dimension2);
    for (int i = 0; i < extraCounter; i++)
        printf("%d: [[%s]]\n", i, extras[i]);

    return 0;
}

当运行时,它会产生:

Dimensions: 10x16
0: [[16]]
1: [[something]]
2: [[another-thing]]

该代码有问题吗?是的,dimension2 的代码不会重新调用strtok(),因此16 被处理了两次,一次作为维度,一次作为字符串。可能不是想要的。因此:

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

int main(void)
{
    int extraCounter = 0;
    char **extras = 0;
    int tempCounter = 0;
    char *ptr = 0;
    char data[] = "10X16 something another-thing";
    char *token = strtok(data, "X");
    int dimension1 = strtol(token, &ptr, 10);
    int dimension2 = -1;
    while (token !=  NULL)
    {
        if (tempCounter == 0)
        {
            token = strtok(NULL, " ");
            dimension2 = strtol(token, &ptr, 10);
            tempCounter++;
        }
        else
        {
            extras = realloc(extras, (extraCounter + 1) * sizeof(char *));
            extras[extraCounter] = malloc(strlen(token) + 1);
            strcpy(extras[extraCounter++], token);
        }
        token = strtok(NULL, " ");
    }

    printf("Dimensions: %dx%d\n", dimension1, dimension2);
    for (int i = 0; i < extraCounter; i++)
        printf("%d: [[%s]]\n", i, extras[i]);

    return 0;
}

编译:

gcc -g -O3 -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Werror ss.c -o ss

输出:

Dimensions: 10x16
0: [[something]]
1: [[another-thing]]

看起来更好......

【讨论】:

    猜你喜欢
    • 2015-01-31
    • 1970-01-01
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-14
    相关资源
    最近更新 更多