0

我正在尝试解决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;
}

我试图用向量解决它,而不使用标志,我的所有解决方案都返回了错误。此外,在我所有的实验中,这是最糟糕的一个,但也是唯一剩下的一个。
以下是本书提供的库。下面的所有代码都是由 Bruce Eckel 编写的。
CppLib.cppCppLib.hStack.cppStack.hrequire.h

4

3 回答 3

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.

于 2013-04-15T10:07:17.853 回答
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;
}
于 2015-07-09T05:45:18.887 回答
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");
}
于 2020-03-20T11:46:36.940 回答