我正在尝试解决 Thinking in C ++ 中的练习22(第4章),但有些东西我不见了,因为经过几天的工作,我的解决方案不做这是工作。我不太喜欢在解决练习方面寻求帮助,但在这一刻我感到不知所措。
创建一个包含Stashes的堆栈。每个Stash将保持五行 来自输入文件。使用new创建Stashes。将文件读入 你的堆栈,然后通过从中提取它以原始形式重新打印它 堆栈。
#include "CppLib.h"
#include "Stack.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
//typedef unsigned int uint;
int main() {
ifstream in("main.cpp");
Stack stackStashes;
stackStashes.initialize();
Stash linesStash;
linesStash.initialize(sizeof(char) * 80);
string line;
bool flag = true;
while (flag) {
for (int i = 1; flag && (i <= 5); i++)
if ((flag = (bool)getline(in, line)))
linesStash.add(line.c_str());
if (flag) {
stackStashes.push(new Stash(linesStash));
linesStash.cleanup();
linesStash.initialize(sizeof(char) * 80);
}
}
Stash* s;
char* cp;
int z = 0;
while ((s = (Stash*)stackStashes.pop()) != 0) {
while ((cp = (char*)s->fetch(z++)) != 0)
cout << "s->fetch(" << z << ") = "
<< cp << endl;
delete s;
}
s->cleanup();
stackStashes.cleanup();
return 0;
}
我试图用vector解决它,而不使用flag,我的所有解决方案都返回了一个错误。而且,在我的所有实验中,这是更糟糕的,但是唯一剩下的 这是本书提供的图书馆。以下所有代码均由Bruce Eckel撰写 CppLib.cpp,CppLib.h,Stack.cpp,Stack.h,require.h。
答案 0 :(得分:1)
Stash
对象无法复制,但您在此处复制
stackStashes.push(new Stash(linesStash));
会导致程序崩溃。
你根本不知道。你必须像这样重写你的程序
while (flag) {
Stash * stash_ptr = new Stash();
for (int i = 1; flag && (i <= 5); i++)
if ((flag = (bool)getline(in, line)))
stash_ptr->add(line.c_str());
if (flag) {
stackStashes.push(stash_ptr);
}
无论如何,我还没有测试过。关键是它不会复制任何Stash
对象,一切都是通过Stash
指针完成的。
建议你尝试一本更好的书吗?尽管对Bruce Eckel公平,但他可能还没有引入对象复制的概念,并且没有预料到有人会编写试图复制Stash
的代码。
答案 1 :(得分:0)
我也在这个练习中苦苦挣扎,但终于解决了。我希望这就是你要找的东西。
请检查一下这个main.cpp:它与原始资源(你在问题中已经链接)一样工作,而不对其进行任何修改。
我希望这会有所帮助。如果有什么不清楚,请随时询问。
//Create a Stack that holds Stashes. Each Stash will hold
//five lines from an input file. Create the Stashes using
//new. Read a file into your Stack, then reprint it in its
//original form by extracting it from the Stack.
#include <iostream>
#include <fstream>
#include "cpplib.h"
#include "stack.h"
#include <stdexcept>
#include <string>
#include <cstdlib>
const std::string FILENAME = "file.txt";
const unsigned int LINES_PER_STASH = 5;
const unsigned int MAX_LINE_LENGTH = 80;
int main(){
std::ifstream in;
try
{
in.open(FILENAME.c_str(),std::ios_base::in);
if(!in.is_open())
{
throw new std::exception();
}
}
catch(...)
{
std::cout << "Error should be handled" << std::endl;
exit(-1);
}
unsigned int lineCount = 0;
Stack stack;
stack.initialize();
Stash* pStash = 0;
std::string line;
while(std::getline(in, line) )
{
if(! (lineCount % LINES_PER_STASH))
{
if(lineCount)
{
stack.push(pStash);
}
pStash = new Stash();
pStash->initialize(MAX_LINE_LENGTH);
}
pStash->add(line.c_str());
lineCount++;
}
if(0 < pStash->count()) {
stack.push(pStash);
}
in.close();
Stash* tempStash;
Stack* pTempStack = new Stack();
pTempStack->initialize();
//revert the order of stashes in a new stack
while((tempStash = static_cast<Stash*>(stack.pop())) != 0)
{
pTempStack->push(tempStash);
}
stack.cleanup();
while(0 != (tempStash = static_cast<Stash*>(pTempStack->pop()) ) )
{
//a more elegant and consistent way should be to solve this loop with 'while', still 'for' and worked fine at first try, so I left it as it is:
for(int i = 0; i < LINES_PER_STASH; i++){
std::cout << (char*)tempStash->fetch(i) << std::endl;
}
delete tempStash;
}
pTempStack->cleanup();
delete pTempStack;
return 0;
}
答案 2 :(得分:0)
我也有练习23的解决方案。
修改练习22,以便您创建一个结构来封装堆栈。用户只能通过成员函数来添加和获取行,但是在隐蔽的情况下,该结构恰巧使用了堆栈堆栈。
Stack.cpp的源代码
#include "CppLib.h"
#include "Stack.h"
#include "require.h"
using namespace::std;
const int bufsize = 80;
void Stack::Link::initialize(Stash* dat, Link* nxt) {
data = dat;
next = nxt;
}
void Stack::initialize() {
head = 0;
Stash* stash = new Stash;
stash->initialize(sizeof(char) * bufsize);
Link* newLink = new Link;
newLink->initialize(stash, head);
head = newLink;
}
void Stack::push(const void * element) {
// each stash stores 5 lines
if (head->data->count() < 5) {
head->data->add(element);
} else {
// Push old stash
Link* newLink = new Link;
newLink->initialize(head->data, head);
head = newLink;
// Create new stash
Stash* newStash = new Stash;
newStash->initialize(sizeof(char) * bufsize);
head->data = newStash;
// Add element to new stash
head->data->add(element);
}
}
void* Stack::peek() {
require(head != 0, "Stack empty");
return head->data->fetch(head->data->next);
}
void* Stack::pop() {
if (head == 0) return 0;
void* result;
Stash* stash = head->data;
int index = stash->next;
// retrieve next stash
if (index < 1) {
stash->cleanup();
head = head->next;
if (head == 0) return 0; // Check if next stash exists
stash = head->data;
index = stash->next;
}
// pop 5 lines within stash
result = stash->fetch(index - 1);
stash->next = index - 1;
return result;
}
void Stack::cleanup() {
require(head == 0, "Stack not empty");
}