制作通用功能以将项目加载到链接列表中

时间:2014-08-29 23:39:46

标签: c list linked-list strtok

好的,在这里开始C程序员。我正在尝试做的是创建一个从文本文件填充链表的函数。到目前为止我所做的是使用fgets()和strtok()迭代文本文件,我试图将标记化的字符串加载到一个函数中来填充链表。首先,当我使用strtok时,如何将标记化的字符串捕获到char数组或字符串中?到目前为止,我尝试过这样的事情:

char catID[ID_LEN+1];
char drinkType[1];
char itemName[MAX_NAME_LEN + 1];

while((fgets(line, sizeof(line), menufile)) != NULL) {   
  token = strtok(line, "|");
  strcpy(data,strdup(token));
  addCatNode(menu, catID);
  printf("%s\n", catID);
  i++;
  while(token){

      if(token)
      {
          strcpy(drinkType,strdup(token));
          addNodeItem(&menu, drinkType);
          strcpy(itemName,strdup(token));
           addNodeItem(&menu, itemName);
           token = strtok(NULL, "|");

      }

  }
}

但不知何故,我不认为这是正确的做法。当然,当我尝试将数据加载到addNodeItem()函数时,其原型我写得像这样:

void addNodeItem(BCSType* menu, char *nodeitem);

并尝试使用此表示法添加项目:

category->nodeitem

编译器告诉我结构中没有名为'nodeitem'的成员。当然没有,但我正在尝试从strtok()部分加载名称,那么如何让addNodeItem()函数识别我试图传递给它的名称?这里很困惑。

链表中的“category”结构如下所示:

typedef struct category
{
   char categoryID[ID_LEN + 1];
   char categoryName[MAX_NAME_LEN + 1];
   char drinkType;      /* (H)ot or (C)old. */
   char categoryDescription[MAX_DESC_LEN + 1];
   CategoryTypePtr nextCategory;
   ItemTypePtr headItem;
   unsigned numItems;
} CategoryType;

1 个答案:

答案 0 :(得分:0)

这里有几个问题,但对于初学者来说,strcpy(drinkType, strdup(token))并没有多大意义。

token是指向输入字符串的一部分的指针,其中包含' |'分隔符由NULL替换 strdup分配strlen(token)内存并复制token的内容。到现在为止还挺好。它返回新内存的地址,您不会将其存储在任何地方,因此您永远不能free()它。这是一个泄漏,你最终可能会耗尽内存。

strcpy(drinkType,strdup(token))将新内存复制到drinkType指向的内存中。这只有1个字符。我不知道这是否足够大。你也没有,因为你正在加载的文件中可能有任何内容。这是一个等待发生的错误。

然后似乎addNodeItem()函数缺少某些东西。您传递的值代表结构中的一个可能值,无法指定哪一个。您可以更好地创建CategoryType的本地副本,从标记生成器分配所有信息,然后将整个事物复制到新节点中。

算法概要:

while lines:
  CategoryType newCat
  tokenize line
  copy tokens into correct members of newCat, using `strncpy` to ensure no overruns.
  add newCat to linked List. 

对于最后一步,您需要在添加newCat之前复制它,因为在处理下一行时它将被覆盖。您可以将副本传递给AddNodeItem,也可以让AddNodeItem进行复制。 (还有其他选择,但这些可能最直接。)