可以在这里开始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("%sn", 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()函数识别我试图传递给它的名称呢?这里很混乱。
链表中的"类别"结构如下所示:
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;
这里有几个问题,但对于初学者来说,strcpy(drinkType, strdup(token))
没有多大意义。
token
是指向输入字符串的一部分的指针,分隔符"|"被NULL替换
CCD_ 3分配相当于CCD_ 4的存储器并复制CCD_。到目前为止还不错。它返回新内存的地址,你不会把它存储在任何地方,所以你永远不能free()
它。这是一个泄漏,你最终可能会耗尽内存。
CCD_ 7将该新存储器复制到CCD_。这只是一个字符。我不知道这是否足够大。你也没有,因为你正在加载的文件中可能有任何内容。这是一个等待发生的错误。
然后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制作副本。(还有其他选项,但这些可能是最简单的。)