尝试从类数组输出字符串时std :: length_error

时间:2014-02-19 05:31:44

标签: c++ arrays string class c++11

我的程序包含三个文件。 arithcard.hpp(header),assign2.cpp(主程序)和arithcard.cpp(方法)。

在数组中,cards是从文本文件中读取的存储字符串。例如,cards [0] .fileLine的字符串为2 + 2 = 4.(fileLine是包含所有字符串的私有成员变量),cards [1] .fileLine的字符串为2 + 4 = 3等...

我知道cards [i] .fileLine包含所有这些字符串,因为我通过在readCards方法中将它们全部打印出来进行测试,看看它们是否真的在那里。

这是我的问题,当我尝试在主程序中调用cards [i] .getQuestion(或.getAnswer())时。有时,它会向我显示问题(或答案)或错误

“在抛出'std :: length_error'的实例后终止调用   what():basic_string :: _ S_create“

arithcard.hpp

#include <iostream>
#include <string>

/*
  Defines the class ArithCard, for handling arithmetic flash cards.

  You may not modify the public method declarations provided below. The main
  program used to test your solution will assume that these methods exist.

  You can add private attributes and methods as you need them.

  You may find it convenient to add additional public methods for testing.
  Keep in mind that your code must work with the unmodified main program
  or it will fail automated testing.
*/
class ArithCard {

  public:

  // Default constructor
  ArithCard() ;

  static bool readCards(const std::string &fileName,
            int &cardCnt,ArithCard *&cards) ;

  void displayQuestion(std::ostream &out) ;

  bool checkAnswer(std::istream &in) ;

  // Return the question as a string.
  std::string getQuestion() ;

  // Return the answer as a string.
  std::string getAnswer() ;

  // Return the answer as an integer.
  int getAnswerValue() ;

  private:

  // Add your private methods and attributes here.
  std::string fileLine;
  std::string question;
  std::string answer;
} ;

arithcard.cpp

#include <iostream>
#include <string>
#include <fstream>
#include "arithcard.hpp"
using namespace std;

ArithCard::ArithCard()
{
    //body intentionally empty
}

bool ArithCard::readCards(const string &fileName, int &cardCnt, ArithCard *&cards)
{
    //read the file line by line and store it in cards
    return (true);
}

void displayQuestion(std::ostream &out)
{
   //display output
}

 bool checkAnswer(std::istream &in)
 {
     return (true);
 }

// Return the question as a string.
 string ArithCard::getQuestion()
 {
     size_t pos = 0;
     pos = fileLine.find("=");
     question = fileLine.substr(0, pos);
     return question;
 }

 // Return the answer as a string.
  string ArithCard::getAnswer()
  {
      size_t pos = 0;
      pos = fileLine.find("=") + 1;
      answer = fileLine.substr(pos);
      return answer;
  }

    // Return the answer as an integer.
   int getAnswerValue()
   {
       return answer;

   }

assign2.cpp

#include <iostream>
#include <sstream>
#include <string>
#include <limits>
#include <random>
#include "arithcard.hpp"

// File-local anonymous namespace

namespace {

int verbosity = 1 ;

}

/*
  Read in the files of cards, then loop: query the user to specify a
  question, print the question, check the answer. Terminate when the user
  types an empty line instead of specifying a question.
*/
int main (int argc, const char *argv[])
{
  if (argc != 2) {
    std::cout << "Usage: " << argv[0] << " <datafile>" << std::endl ;
    return (1) ;
  }
  std::string dataFile(argv[1]) ;

  bool result = false ;
  int cardCnt = -1 ;
  ArithCard *cards = nullptr ;

/*
  Parse the file of questions & answers. A false return value indicates an
  absent file or other i/o error. It's also possible the file is present but
  contains no valid questions.
*/
result = ArithCard::readCards(dataFile,cardCnt,cards) ;
std::cout << cards[0].getQuestion() << std:: endl;

  return (0) ;
}

1 个答案:

答案 0 :(得分:1)

来自§21.4.2/ 1 [string.require]

  

如果任何操作导致size()超过max_size(),该操作将抛出length_error类型的异常对象。

所以你的代码中某处你试图创建一个长度超过string::max_size()的字符串,这通常是一个很大的数字,所以你应该为自己感到骄傲: - )

除了笑话之外,很难分辨出错误的位置,因为看起来你已经删除了相关的代码段,尤其是ArithCard::readCards的实现。我不明白为什么你选择创建这个函数static,然后传递一个指向ArithCard实例的指针,而不仅仅是使它成为一个非静态成员函数。

你的代码有你传递给ArithCard::readCards的指针初始化为nullptr,所以我假设你正在为函数内的对象分配内存。如果你不是,那么你很可能在该函数中有未定义的行为。

我将该功能更改为

class ArithCard {
  public:
  ...
  bool readCards(const std::string &fileName, int &cardCnt) ;
};

并将main()中的代码更改为

ArithCard cards;

result = cards.readCards(dataFile, cardCnt);

此外,在getQuestion()getAnswer()中,您没有检查string::find的返回值,因此尝试使用无效结果提取子字符串可能是导致此错误的原因。这是最可能的解释,因为如果找不到搜索字词,string::find将返回string::npos,这是一个很大的数字。