下推栈实现(c++编程思想 p136)
1 头文件Stack.h
1 #ifndef STACK_H 2 #define STACK_H 3 4 struct Stack 5 { 6 7 struct Link 8 { 9 void* data; 10 Link* next; 11 void initialize(void* dat, Link* nxt); 12 }* head; 13 14 void initialize(); 15 void push(void* dat); 16 void* peek(); 17 void* pop(); 18 void cleanup(); 19 }; 20 21 #endif // STACK_H
2 实现文件Stack.cpp
1 #include "Stack.h" 2 #include "../require.h" 3 4 using namespace std; 5 6 void Stack::Link::initialize(void* dat, Link* nxt) 7 { 8 data = dat; 9 next = nxt; 10 } 11 12 void Stack::initialize() 13 { 14 head = 0; 15 } 16 17 void Stack::push(void* dat) 18 { 19 Link *newLink = new Link; 20 newLink->initialize(dat, head); 21 head = newLink; 22 } 23 24 void* Stack::peek() 25 { 26 require(head !=0, "Stack empty"); 27 return head->data; 28 } 29 30 31 void* Stack::pop() 32 { 33 if (head == 0) 34 return 0; 35 void* result = head->data; 36 Link* oldHead = head; 37 head = head->next; 38 delete oldHead; 39 return result; 40 } 41 42 43 void Stack::cleanup() 44 { 45 require(head == 0, "Stack not empty"); 46 }
3 测试文件main.cpp
1 #include <iostream> 2 #include <fstream> 3 #include <string> 4 #include "Stack.h" 5 #include "../require.h" 6 7 using namespace std; 8 9 int main(int argc, char* argv[]) 10 { 11 12 requireArgs(argc, 1); 13 14 ifstream in(argv[1]); 15 assure(in, argv[1]); 16 17 Stack textLines; 18 textLines.initialize(); 19 20 string line; 21 while (getline(in, line)) //文件以行为单位入栈 22 textLines.push(new string(line)); 23 24 string* s; 25 while ((s = (string*) textLines.pop()) != 0) //出栈 26 { 27 cout << *s << endl; 28 delete s; 29 } 30 31 textLines.cleanup(); 32 return 0; 33 }
4 运行分析
附 辅助测试工具require.h
1 #ifndef REQUIRE_H 2 #define REQUIRE_H 3 4 #include <cstdio> 5 #include <cstdlib> 6 #include <fstream> 7 #include <string> 8 9 inline void require(bool requirement, const std::string& msg = "Requirement failed") 10 { 11 using namespace std; 12 if (!requirement) 13 { 14 fputs(msg.c_str(), stderr); 15 fputs("\n", stderr); 16 exit(1); 17 } 18 } 19 20 inline void requireArgs(int argc, int args, const std::string& msg = "Must use %d arguments") 21 { 22 using namespace std; 23 if (argc != args + 1) 24 { 25 fprintf(stderr, msg.c_str(), args); 26 fputs("\n", stderr); 27 exit(1); 28 } 29 } 30 31 inline void requireMinArgs(int argc, int minArgs, const std::string& msg ="Must use at least %d arguments") 32 { 33 using namespace std; 34 if(argc < minArgs + 1) 35 { 36 fprintf(stderr, msg.c_str(), minArgs); 37 fputs("\n", stderr); 38 exit(1); 39 } 40 } 41 42 inline void assure(std::ifstream& in, const std::string& filename = "") 43 { 44 using namespace std; 45 if(!in) 46 { 47 fprintf(stderr, "Could not open file %s\n", 48 filename.c_str()); 49 exit(1); 50 } 51 } 52 53 inline void assure(std::ofstream& out, const std::string& filename = "") 54 { 55 using namespace std; 56 if(!out) { 57 fprintf(stderr, "Could not open file %s\n", 58 filename.c_str()); 59 exit(1); 60 } 61 } 62 63 64 #endif // REQUIRE_H