动态堆栈分配(来自C+;+;)中的思考) 我试图从C++中的练习中解题22(第4章),但是有些东西我错过了,因为在几天的工作之后,我的解决方案不起作用。我不太喜欢在解决练习时寻求帮助,但在这一刻我感到不知所措

动态堆栈分配(来自C+;+;)中的思考) 我试图从C++中的练习中解题22(第4章),但是有些东西我错过了,因为在几天的工作之后,我的解决方案不起作用。我不太喜欢在解决练习时寻求帮助,但在这一刻我感到不知所措,c++,stack,C++,Stack,创建一个包含隐藏的堆栈。每个储藏室可容纳五行 从输入文件。使用new创建隐藏。将文件读入 您的堆栈,然后通过从 那一堆 #包括“CppLib.h” #包括“Stack.h” #包括 #包括 #包括 #包括 使用名称空间std; //typedef无符号整数单元; int main(){ ifstream in(“main.cpp”); 堆垛; stackstaches.initialize(); 隐藏线; linesStash.initialize(sizeof(char)*80); 弦线; 布

创建一个包含隐藏的堆栈。每个储藏室可容纳五行 从输入文件。使用new创建隐藏。将文件读入 您的堆栈,然后通过从 那一堆

#包括“CppLib.h”
#包括“Stack.h”
#包括
#包括
#包括
#包括
使用名称空间std;
//typedef无符号整数单元;
int main(){
ifstream in(“main.cpp”);
堆垛;
stackstaches.initialize();
隐藏线;
linesStash.initialize(sizeof(char)*80);
弦线;
布尔标志=真;
while(旗帜){
对于(inti=1;标志&&(i获取(z++)!=0)

cout哇,那太糟糕了。恐怕你的代码没有问题,只有Bruce Eckel的。问题是
隐藏的对象无法复制,但你在这里复制了一个

 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);
    }
while(标志){
隐藏*Stash_ptr=新的隐藏();
对于(inti=1;标志&&(i添加(line.c_str());
国际单项体育联合会(旗){
stackstacks.push(stash_ptr);
}
不管怎么说,我还没有测试过它。关键是它没有复制任何
隐藏
对象,一切都是通过
隐藏
指针完成的


建议您尝试一本更好的书?虽然对Bruce Eckel公平地说,他可能还没有引入对象复制的概念,也没有预料到有人会编写试图复制
隐藏的代码,但我也为此做了很多努力,但最终解决了。我希望这就是您所寻找的

请检查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;
}
//创建一个包含隐藏内容的堆栈。每个隐藏内容都将包含
//输入文件中的五行。使用
//新建。将文件读入堆栈,然后在其
//从堆栈中提取原始表单。
#包括
#包括
#包括“cpplib.h”
#包括“stack.h”
#包括
#包括
#包括
const std::string FILENAME=“file.txt”;
常量无符号整数行每存储=5;
常量无符号整数最大线长度=80;
int main(){
std::ifstream-in;
尝试
{
in.open(FILENAME.c_str(),std::ios_base::in);
如果(!in.is_open())
{
抛出新的std::exception();
}
}
捕获(…)
{
std::cout add(line.c_str());
lineCount++;
}
如果(0count()){
堆栈推送(pStash);
}
in.close();
隐藏*临时隐藏;
Stack*pTempStack=新堆栈();
pTempStack->initialize();
//恢复新堆栈中的存储顺序
而((tempStash=static_cast(stack.pop())!=0)
{
pTempStack->push(临时存储);
}
stack.cleanup();
而(0!=(tempStash=static_cast(pTempStack->pop()))
{
//一种更优雅、更一致的方法应该是使用“while”来解决这个循环,仍然是“for”,并且在第一次尝试时工作得很好,所以我将它保持原样:
对于(int i=0;i
我也找到了练习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");
}
#包括“CppLib.h”
#包括“Stack.h”
#包括“require.h”
使用namespace::std;
const int bufsize=80;
无效堆栈::链接::初始化(隐藏*dat,链接*nxt){
数据=dat;
next=nxt;
}
void Stack::initialize(){
水头=0;
藏匿*藏匿=新藏匿;
隐藏->初始化(大小(字符)*bufsize);
Link*newLink=新链接;
新建链接->初始化(隐藏,头部);
head=newLink;
}
void Stack::push(const void*元素){
//每个储藏室可储存5行
如果(头部->数据->计数()<5){
表头->数据->增加(要素);
}否则{
//推陈出新
Link*newLink=新链接;
新建链接->初始化(头部->数据,头部);
head=newLink;
//创建新的存储
隐藏*newStash=新的隐藏;
newStash->initialize(sizeof(char)*bufsize);
head->data=newStash;
//将元素添加到新的存储
表头->数据->增加(要素);
}
}
void*Stack::peek(){
要求(头部=0,“堆栈为空”);
返回head->data->fetch(head->data->next);
}
void*Stack::pop(){
如果(head==0)返回0;
无效*结果;
隐藏*隐藏=头部->数据;
int index=stash->next;
//取回下一个藏品
如果(指数<1){
隐藏->清理();
头部=头部->下一步;
if(head==0)返回0;//检查下一个隐藏是否存在
隐藏=头部->数据;
索引=隐藏->下一步;
}
//在藏匿处弹出5行
结果=隐藏->提取(索引-1);
隐藏->下一步=索引-1;
返回结果;
}
void Stack::cleanup(){
require(head==0,“堆栈不为空”);
}

错误是?我想这是我今天第四次或第五次这样说了,现在才10:49。这不起作用吗?当你试图运行控制台时,重新运行一些行,然后windows终止线程。@sftrabbit这意味着你起得太早:)您的测试将丢失文件的最后几行,因为除非文件以5行的倍数结尾,否则标志将为false。请检查是否为空。否则,代码看起来很好,但是..当我编写时,我非常确定它的任务应该是“获取Stac”
#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");
}