我有像(Student (Name x) (Age y))
这样的模板。我可以通过使用以下内容检查名为Name
的广告位的所有事实来获取Name
的值:
EnvGetFactList(theEnv, &factlist, NULL);
if (GetType(factlist) == MULTIFIELD)
{
end = GetDOEnd(factlist);
multifieldPtr = GetValue(factlist);
for (i = GetDOBegin(factlist); i <= end; i++)
{
EnvGetFactSlot(theEnv,GetMFValue(multifieldPtr, i),"Name",&theValue);
buf = DOToString(theValue);
printf("%s\n", buf);
}
}
我想检查这个事实是否属于Student
类型。如果是,请获取Name
插槽的值。
我想我应该使用EnvFactDeftemplate
,但我无法让它发挥作用。这是我的代码
templatePtr = EnvFindDeftemplate(theEnv, "Student");
templatePtr = EnvFactDeftemplate(theEnv,templatePtr);
EnvGetFactSlot(theEnv,&templatePtr,"Name",&theValue);
但我得到以下运行时错误:Segmentation fault (core dumped)
。问题在哪里?
答案 0 :(得分:0)
EnvGetFactSlot期望指向事实的指针,而不是指向deftemplate的指针。使用EnvGetNextFact函数之一而不是EnvGetFactList来迭代事实也更容易。这是一个有效的例子:
int main()
{
void *theEnv;
void *theFact;
void *templatePtr;
DATA_OBJECT theValue;
theEnv = CreateEnvironment();
EnvBuild(theEnv,"(deftemplate Student (slot Name))");
EnvBuild(theEnv,"(deftemplate Teacher (slot Name))");
EnvAssertString(theEnv,"(Student (Name \"John Brown\"))");
EnvAssertString(theEnv,"(Teacher (Name \"Susan Smith\"))");
EnvAssertString(theEnv,"(Student (Name \"Sally Green\"))");
EnvAssertString(theEnv,"(Teacher (Name \"Jack Jones\"))");
templatePtr = EnvFindDeftemplate(theEnv,"Student");
for (theFact = EnvGetNextFact(theEnv,NULL);
theFact != NULL;
theFact = EnvGetNextFact(theEnv,theFact))
{
if (EnvFactDeftemplate(theEnv,theFact) != templatePtr) continue;
EnvGetFactSlot(theEnv,theFact,"Name",&theValue);
EnvPrintRouter(theEnv,STDOUT,DOToString(theValue));
EnvPrintRouter(theEnv,STDOUT,"\n");
}
EnvPrintRouter(theEnv,STDOUT,"-------------\n");
for (theFact = EnvGetNextFactInTemplate(theEnv,templatePtr,NULL);
theFact != NULL;
theFact = EnvGetNextFactInTemplate(theEnv,templatePtr,theFact))
{
EnvGetFactSlot(theEnv,theFact,"Name",&theValue);
EnvPrintRouter(theEnv,STDOUT,DOToString(theValue));
EnvPrintRouter(theEnv,STDOUT,"\n");
}
}