2012-04-15 81 views
0

我想解析一个C++作业的HTML文件。该任务正在演示堆栈;我们应该在每次碰到标签时推入堆栈,然后在找到相应的结束标签时弹出。如何使用变量的值在我的代码中执行某些操作?

老师显然要我们硬编码一组标记检测,如:

// Declare some stacks 
Stack html; 
Stack div; 
... 

// When you find an open tag, push to the corresponding stack 
if (tagcontents == "html") { html.push(); } 
if (tagcontents == "div") { div.push(); } 
... 

// When you find a close tag, push to the corresponding stack 
if (tagcontents == "/html") { html.pop(); } 
if (tagcontents == "/div") { div.pop(); } 
... 

这样做的明显缺点是,如果我想支持all of the tags available in HTML,我可以期望做大量的冗余编码。老师显然希望我们只挑选一小部分可用标签,然后去掉这些标签,但我认为这是跛子。由于我很懒(我坚信所有程序员都应该这样做),所以我试图想出一个动态解决方案。

这个想法是,每当我遇到一个新的标签时,为它创建一个堆栈。这将允许我的程序支持任何标签,而不管其有效性。尽管如此,我遇到了一个有趣的理论问题,我甚至不知道该怎么称呼它才能研究它。也就是说,我需要使用变量的VALUE作为我的实际代码的一部分。 IE:

if (no stack exists named "HTML") { create a stack named "HTML" } 

在简单的话来说,我怎能:

tag = "html"; 
Stack tag; // make a stack named HTML? 

或者有另一种方式做到这一点?任何帮助将不胜感激。如果我无法弄清楚这一点,我可能只会使用一个开关/ case声明,就像一个quitter。

回答

0

std::map<std::string, Stack>内部创建堆栈。

0

使用地图/无序地图:

std::map <std:string, Stack> myStacks;

然后,你可以做

myMastacks[tagcontents].push()

此,如果一个不存在将初始化一个新的堆栈的关键。

在标签的末尾,剥去斜线,检查它是否在地图上,然后你去了。

0

我会以不同的方式做到这一点,更简单,只有一个堆栈的所有标签(我认为这是非常合理的,除非你的老师实际指示你使用多个堆栈):声明一堆字符串。一个字符串表示一个标签。您可以使用STL堆栈这样的:

stack<string> my_tags;

my_tags.push("div")将推动“格”入堆栈。 string tag = my_tags.top();将查询堆栈的顶部,并且my_tags.pop()将弹出堆栈中的顶部项目。非常容易:-)

同样,如果您不需要练习几个堆栈,但要检查您在html解析中的位置,这种解决方案很好。

+0

但是,这只是测试同等数量的代码打开标签和关闭标签的,对不对?我需要在原始标签上抛出错误。这是一个有趣的提议,因为AFAIK有效的HTML需要所有的标签嵌套,因此你永远不会有像

这样的东西。嗯,我必须进一步调查。 – 2012-04-15 19:00:34

0

下面是一个例子:

#include <stdio.h> 
#include <map> 
#include <string> 
#include <list> 
#include <iostream> 

typedef std::list<std::string> stack; 
typedef std::map<std::string, stack> stack_map; 

stack_map my_stacks; 

stack& getStack(const std::string& stack_name) { 
    stack_map::iterator it = my_stacks.find(stack_name); 
    if(it != my_stacks.end()) { 
     return it->second; 
    } else { 
     my_stacks[stack_name] = stack(); 
     return my_stacks[stack_name]; 
    } 
} 


... 
stack& div_stack = getStack("div"); 

// and use that for example 
div_stack.push_back("some info"); 
div_stack.push_back("some more info ... "); 
div_stack.push_back("s even more ... "); 

..... 
相关问题