在构造函数中,当name是 a时,您:name(name)
不会做您所期望的事情,您不会深度复制名称,而只是保存因未定义行为而变得无效的指针(并丢失了产生内存泄漏的分配数组)。char*
switch
char
使用 astd::string
而不是 a char*
,您将获得预期的行为。这也大大简化了复制、分配、删除节点时的管理,因为您无事可做,而使用指针则不是这种情况。
char name[6];
如果有超过 5 个字符的单词可用,那么它会以未定义的行为从scanf("%s", &name);
数组中写入。
您也不会检查scanf
成功检查它们返回 1 的调用,如果输入无效,您将不受保护。
请注意,您可以使用iostream功能(也检查读数是否成功),而不是使用 C 函数来读/写。
选择 astd::stack
而不是例如 astd::vector
很奇怪,因为编写它的内容不太实用。
一种方法是在编写其 contains 时不清空堆栈:
#include <iostream>
#include <string.h>
#include <stack>
#include <limits>
struct Node
{
std::string name;
float sumary;
int amount;
Node(std::string name, float sumary, int amount)
:name(name), sumary(sumary), amount(amount) {
}
Node() {}
};
void inputError(const char * msg)
{
if (std::cin.rdstate() & std::istream::eofbit)
{
// EOF
std::cerr << "EOF, abort" << std::endl;
exit(-1);
}
std::cerr << msg << std::endl;
std::cin.clear();
// flush all the line, you can just read a word
// with "string s; cin >> s;" if you prefer
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
int main()
{
int command;
std::stack<Node> node;
for (;;)
{
std::cout << "Input command:\n 1 - add,\n 2 - delete last,\n 3 - show all,\n 4 - exit" << std::endl;
if (!(std::cin >> command))
inputError("invalid command, not an integer");
else
{
switch (command)
{
case 1:
{
std::string name;
float sumary;
int amount;
if (!(std::cout << "Enter name: ", std::cin >> name) ||
!(std::cout << "Enter sumary: ", std::cin >> sumary) ||
!(std::cout << "Enter amount: ", std::cin >> amount))
inputError("invalid value");
else
node.push(Node(name, sumary, amount));
}
break;
case 2:
if (node.empty())
std::cerr << "no node to delete" << std::endl;
else
{
node.pop();
std::cout << "The last have been deleted" << std::endl;
}
break;
case 3:
{
std::stack<Node> temp = node;
while (!temp.empty())
{
const Node & n = temp.top();
temp.pop();
std::cout << n.name << " " << n.sumary << " " << n.amount << std::endl;
}
}
break;
case 4:
return 0;
default:
std::cerr << "Wrong command number" << std::endl;
break;
}
}
}
}
编译和执行:
pi@raspberrypi:/tmp $ g++ -Wall c.cc
pi@raspberrypi:/tmp $ ./a.out
Input command:
1 - add,
2 - delete last,
3 - show all,
4 - exit
7
Wrong command number
Input command:
1 - add,
2 - delete last,
3 - show all,
4 - exit
z
invalid command, not an integer
Input command:
1 - add,
2 - delete last,
3 - show all,
4 - exit
1
Enter name: aze
Enter sumary: a
invalid value
Input command:
1 - add,
2 - delete last,
3 - show all,
4 - exit
1
Enter name: aze
Enter sumary: 1.1
Enter amount: 2
Input command:
1 - add,
2 - delete last,
3 - show all,
4 - exit
1
Enter name: qsd
Enter sumary: 2.2
Enter amount: 3
Input command:
1 - add,
2 - delete last,
3 - show all,
4 - exit
3
qsd 2.2 3
aze 1.1 2
Input command:
1 - add,
2 - delete last,
3 - show all,
4 - exit
3
qsd 2.2 3
aze 1.1 2
Input command:
1 - add,
2 - delete last,
3 - show all,
4 - exit
2
The last have been deleted
Input command:
1 - add,
2 - delete last,
3 - show all,
4 - exit
3
aze 1.1 2
Input command:
1 - add,
2 - delete last,
3 - show all,
4 - exit
4
pi@raspberrypi:/tmp $
operator<<
在Node中定义而不是将其成员公开以便能够在main中访问它们以编写它们也是一个好主意