好的,在这里开始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;
答案 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进行复制。 (还有其他选择,但这些可能最直接。)