【问题标题】:std::length_error when trying to output a string from class array尝试从类数组输出字符串时出现 std::length_error
【发布时间】:2014-03-19 06:38:28
【问题描述】:

我的程序由三个文件组成。 arithcard.hpp(标题)、assign2.cpp(主程序)和 arithcard.cpp(方法)。

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

我知道 card[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) ;
}

【问题讨论】:

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


    【解决方案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,这是一个巨大的数字。

    【讨论】:

    • 我不打算更改 main() 或函数标题。你的建议可能是我收到错误的原因。我会试着看看为什么它找不到我的字符串值。
    猜你喜欢
    • 1970-01-01
    • 2021-07-13
    • 2014-05-28
    • 2018-04-24
    • 2015-07-15
    • 1970-01-01
    • 2020-08-17
    • 2018-02-11
    • 1970-01-01
    相关资源
    最近更新 更多