如何在C中的文本文件中的标记之间解析数据

我想使用C在文本文件中打印标签之间的数据。

输入声明:( PERSON)Mark Zuckerberg(/ PERSON)是(LOCATION)USA(/ LOCATION)的企业家。 他还是(ORGANIZATION)Facebook(/ ORGANIZATION)的首席执行官。

输出:马克扎克伯格美国Facebook。

我的程序代码是:

const char* getfield(char* line, int num) { const char* tok; for (tok = strtok(line, "/>"); tok && *tok; tok = strtok(NULL, "<\n")) { if (!--num) return tok; } return NULL; } int main() { char line[500000]; while (fgets(line, 500000, stdin)) { char* tmp = strdup(line); printf(" %s\n", getfield(tmp, 2)); free(tmp); } } 

它只印刷马克扎克伯格。 标签之间的其他数据没有显示? 有人可以在我出错的地方帮忙吗? 我刚开始用C学习文件处理,因此非常感谢指导。 谢谢。

编辑:请用“/>”替换“(”by“<”和“)”。

你的getfield没有做我想要的。 在示例字符串(重新加注括号)上,你的for循环开始strtok将在第一个“>”处切换( strtok使用任何字符作为分隔符),因此在第一个“PERSON”之后。 之后你只剪切了“> \ n”,所以在这个标签的末尾。 如果数量足够大,它将给出(在循环内):

  is a entrepreneur from LOCATION> USA /LOCATION>. He is also the CEO of ORGANIZATION> Facebook /ORGANIZATION> 

您应该交替搜索:搜索结束标记(>),然后搜索开始标记(<):beetween是第一个标记的内容。 然后跳过结束标记并再次开始直到结束。 就像是:

 char *gf(char *line, int num) { char *n1, *n2; // comments are for the 1st loop // search end of 1st tag (opening) n1 = strtok(line, ">\n"); while(n1) { // search begin of 2nd tag (correp. closing) n2 = strtok(NULL, "<"); // this one is good, shall we return it? if (num == 0) { return(n2); } printf("Found: %s\n", n2); // search end 2nd tag (have to skip it) n1 = strtok(NULL, ">\n"); // search end of 3rd tag (opening), then loop (same situation) n1 = strtok(NULL, ">\n"); } return NULL; } 

请注意,此代码不是很好。 如果在常规文本中有“>”或“<”,则会出错(就像你自己的代码一样,BTW)。 如果字符串没有以\ n结尾,它就不会正常停止。

注意:如果你需要一个强大的方法,你将不得不阅读标签。 我的意思是找到一个标签(东西在“<”和“>”之间),然后找到相应的结束标签(相同,但使用/和相同的内容),然后只获取内部文本或生成错误。

编辑:我更改了函数,以便它返回第num个元素。 您现在必须处理一个能够多次调用此函数的main()函数,增加num值,存储(或打印)结果,直到获得NULL回答。 作为家庭工作,您将不得不找到如何管理main中的主字符串(行),以便可以进行连续调用(否则您将只获得第一个标记):)

你的fgets()调用正在读取整行。 然后调用getfield()并打印结果。 然后丢弃你读过的其余内容,尝试阅读更多内容,不再有内容,然后退出循环。 只要您有未处理的数据,就需要保持循环。

编辑:这里有一些示例代码可以帮助您入门:

 int main() { char line[500000]; while (fgets(line, 500000, stdin)) { char *arg = line; const char *tok; while ((tok = getfield(arg, 2)) != NULL) { printf("%s\n", tok); arg = NULL; } } } 

但请注意,这不是一个真正的解决方案。 首先,它将为您提供标签之外的文本以及标签内的文本,因此您需要跳过它。 另一方面,如果您的输入文件包含多行,它将无法正常工作。

编辑:在代码和解释中将此更改为()<> 谢谢汤姆。

这是解决方案。 尝试理解代码。 此外,您可以根据自己的需要进行修改。 基本上,您需要做的是通过扫描字符<>来扫描标签<>或/和 > 。 当你遇到字符<增加你的索引,直到你遇到字符>一旦你遇到>字符然后开始复制>字符后面的字符,直到你遇到另一个<字符,然后重复这个过程,直到你到达空终止字符'\0'

 #include //#pragma warning(disable : 4996) void removeTags(char inpData[], int dataLen); int main() { char letter, fileData[400]; int numLetters; FILE *pfile; pfile = fopen("test.txt", "r"); if (pfile == NULL) { printf("Error!Can not open file"); } else { numLetters = 0; while ((letter = fgetc(pfile)) != EOF) { fileData[numLetters] = letter; numLetters++; } fileData[numLetters] = '\0'; printf("File Data:\n\n"); printf("%s", fileData); printf("\nRemoving Tags.....\n"); removeTags(fileData,numLetters); } return 0; } void removeTags(char inpData[],int inpLen) { char character,temp[400]; int index = 0,tindex=0; while (inpData[index] != '\0') { if ((inpData[index] >= 'A' && inpData[index] <= 'Z') || (inpData[index] >= 'a' && inpData[index] <= 'z') || inpData[index] == ' ' || inpData[index] == '.') { temp[tindex] = inpData[index]; index++; tindex++; } else if (inpData[index] == '<') { while (inpData[index] != '>') { index++; } index++; temp[tindex] = ' '; if (tindex > 0) { tindex++; } } else { break; } } temp[tindex] = '\0'; printf("%s", temp); }