1

好的,所以我有这段代码,它可以从文件中提取各种内容

while(fgets(buffer, sizeof(buffer), fp) !=NULL)
{
    name = strtok(buffer,del);
    class=strtok(NULL,del);
    grade = atoi(strtok(NULL,del));


    d[counter].name=name;
    d[counter].course=class;
    d[counter].grade=grade;
    printf("%s    %s     %d\n",d[counter].name,d[counter].course,d[counter].grade);
    counter++;
}

现在的问题是,每次从 strtok 检索新令牌时,它都会替换结构数组中的先前值。

我已经把它缩小到这个有问题的块:

d[counter].name=name;
d[counter].course=class;

它似乎指向同一个内存块,每次 strtok 返回一个新值时都会重新写入该内存块,因此我在结构中的所有指针都指向那个 1 对象。

这是我的结构:

struct student {
char *name;
char *course;
int grade;

};

现在我的问题是,无论如何要将 strtok 值放入单独的内存地址中,这样它们就不会全部指向 1 个位置并替换自己?

Strdup、malloc 和 memmove 不是我的选择。

为了更清楚地表示正在发生的事情,这里是粗略的预期输出

Tom    Phys 1444   54
Joe    CSE 1310   95
Alex   Chem 2315   86
Tim    Span 1443   81

现在这是我得到的输出

Tim  Span 1443  54
Tim  Span 1443  95
Tim  Span 1443  86
Tim  Span 1443  81
4

1 回答 1

1

问题是您有一个缓冲区,每次调用时都会覆盖该缓冲区,fgets并且调用strtok只是将指针返回到该缓冲区。

如果您不允许使用诸如strdup复制strtok调用返回的字符串之类的东西,那么我建议您只使用多个缓冲区。

例如,如果您的缓冲区当前声明为:

char buffer[256];

您可以改为将 20 个缓冲区声明为:

char buffer[20][256];

其中 20 应至少与d数组中的项目数一样大。

然后,您的调用fgets应该根据计数器在循环的每次迭代中读入不同的缓冲区。

fgets(buffer[counter], sizeof(buffer[counter]), fp)

同样,您的调用strtok应该引用适当的缓冲区。

name = strtok(buffer[counter],del);
于 2013-07-14T23:31:55.500 回答