将 strtok 的指针分配给二维结构数组中的指针,所有条目都应该是唯一的,但打印出来是相同的

Assigning pointer from strtok to pointer in 2d array of structs all entries should be unique but print out as identical

正在将指针从 strtok() 分配给结构中包含的 ptr。我有这些结构的二维数组,我想用它来存储我试图从 csv 文件解析的数据。

typedef struct Entry 
{
    char *str;
} Entry; 

我从 fgets() 获取输出并通过我自己的函数 TokenizeLine() 发送它,以便将它拆分并分配到数组中的正确位置。然而,我的二维数组 (etable) 的每个条目中的每个指针最终都持有相同的值。

以下代码有什么问题?

fgets(currentLineStr, 8192, fileIn);

while (currentLineStr[0] == '#')
      fgets(currentLineStr, 8192, fileIn);

TokenizeLine(currentLineStr, eTable, yIndex, x, y);
yIndex++;

while(fgets(currentLineStr, 8192, fileIn) != NULL)
{
      TokenizeLine(currentLineStr, eTable, yIndex, x, y);
      yIndex++;
} 



void TokenizeLine(int x; int y; char currentLineStr[], Entry eTable[x][y], int yIndex, int x, int y)
{
      char *tokPtr;
      int xIndex = 0;

      tokPtr = strtok(currentLineStr, "|");

      while(tokPtr != NULL)
      {
            eTable[xIndex][yIndex].str = tokPtr;
            tokPtr = strtok(NULL, "|");      
            xIndex++;
      } 
 }

在您的代码中,所有 str 本质上都充当 tokPtr 占位符 。他们都只指向tokPtr。现在,在完成 while() 循环后,tokPtr 持有的最新值也将由 allstrs 计算。

要避免,您需要

  1. 为每个 str 分配内存,可能使用 malloc()
  2. 使用strcpy()复制当前tokPtr的值到对应的str.

正如 EOF 在评论中所写,您重用了缓冲区 currentLineStr。每次调用 fgets 时,都会覆盖用于 所有先前行 的存储,包括每个 str 指向的内存。这是因为 strtok returns 指向您首先给它的字符串。

Sourav Ghosh 的解决方案之所以有效,是因为它在遇到共享缓冲区时从共享缓冲区复制每个标记(返回指向副本的指针)。另一个可行的解决方案是 malloc() space for currentLineStr 在你调用 fgets().

的循环中

顺便说一句,我建议您不要这样做:

typedef struct Entry {...} Entry;

C++ 是另一种语言。要么不使用 typedef 并将其命名为 "struct Entry",要么不使用 struct 标记对其进行 typedef:

typedef struct {...} Entry;

C 标准库中有一个约定,typedef 名称以 _t 结尾,因此您也可以这样做(或选择一个对您有意义的命名约定):

typedef struct Entry {...} Entry_t;