使用链接列表实现Stack类。使用堆栈类验证XML文件。 编写C ++程序以从命令行读取XML文件,并验证XML匹配不区分大小写的开始和结束标记。 向所有缺少的相应开始或结束标记提供错误消息,并继续验证所有XML文件。
更正XML文档的示例。
<Students>
<Student>
<Name>Tanver</Name>
<RollNo>312</RollNo>
<student>
<students>
错误的XML文档示例,“head”和“html”结束标记丢失。 “名称”开始标记丢失。
<html>
<head>
<title>My first page</title>
</name>
<body>
My first page
</body>
答案 0 :(得分:0)
我也在训练C ++,并认为这是一个很好的练习。以下是我提出的建议:
#include <iostream>
#include <vector>
#include <string>
#include <regex>
using namespace std;
template <typename T>
class Item {
public:
T data;
Item *prev;
Item(T& data, Item *prev) : data(data), prev(prev) {}
};
template <typename T>
class StackIterator {
public:
Item<T> *curr;
StackIterator(Item<T> *curr) : curr(curr) {}
T& operator*() {
return curr->data;
}
StackIterator<T>& operator++() {
curr = curr->prev;
return *this;
}
friend bool operator!=(const StackIterator<T>& l, const StackIterator<T>& r) {
return l.curr != r.curr;
}
};
template <typename T>
class Stack {
typedef StackIterator<T> iterator;
public:
Item<T> *last=NULL;
T& back(void) {
return last->data;
}
void push_back(T d) {
last = new Item<T>(d, last);
}
void pop_back(void) {
Item<T> *curr = last;
last = last->prev;
delete curr;
}
~Stack() {
while (last) pop_back();
}
iterator begin() {
return iterator(last);
}
iterator end() {
return iterator(NULL);
}
};
int main() {
string xml[] = {"<Students>", "<Student>", "<Name>", "Tanver", "</Name>",
"<RollNo>", "312", "</RollNo>", "</Student>", "</Students>"};
//string xml[] = {"<html>", "<head>", "<title>", "My first page", "</title>",
// "</name>", "<body>", "My first page", "</body>"};
regex opentag("^<(.*)>$");
regex closetag("^</(.*)>$");
smatch m;
Stack<string> v;
//vector<string> v;
for (auto& it : xml) {
if (regex_search(it, m, closetag)) {
for (auto& x : m)
if (x == v.back()) {
v.pop_back();
cout << "closing " << x << "\n";
} else {
cout << "Tag " << x << " was not opened\n";
}
} else if (regex_search(it, m, opentag)) {
for (auto &x : m) {
cout << "opening " << x << "\n";
v.push_back(x);
}
} else {
cout << "data: " << it << "\n";
}
}
for (auto& x : v) {
cout << "Tag " << x << " was not closed\n";
}
}
我没有打扰从命令行部分读取。当然,人们也可以跳过整个StackIterator
的事情,但这就像用普通的C写整篇文章一样。
希望这有帮助!