奇怪的超出范围错误

时间:2014-12-02 14:18:00

标签: c++ range

在下面的代码中,当我运行它时,我面临一个奇怪的超出范围的错误。这段代码是Stroustrup使用C ++编写的“编程原理和实践”一书练习的答案。

#include <Simple_window.h>
#include <iostream>
using namespace std;

//-----------------------------------

class Person
{
public:
    Person(string f_n, string s_n, int a) {
        for(int i=0; i<f_n.size() || i<s_n.size(); i++) 
            if(f_n[i] == ';' || f_n[i] == ':' || f_n[i] == '\'' || 
                f_n[i] == '[' || f_n[i] == ']' || f_n[i] == '*'  || 
                f_n[i] == '&' || f_n[i] == '^' || f_n[i] == '%'  ||
                f_n[i] == '$' || f_n[i] == '#' || f_n[i] == '@'  ||
                f_n[i] == '!' ||
                s_n[i] == ';' || s_n[i] == ':' || s_n[i] == '\'' || 
                s_n[i] == '[' || s_n[i] == ']' || s_n[i] == '*'  || 
                s_n[i] == '&' || s_n[i] == '^' || s_n[i] == '%'  ||
                s_n[i] == '$' || s_n[i] == '#' || s_n[i] == '@'  ||
                s_n[i] == '!')
                error("Bad characters!");
        first_name =  f_n;
        second_name = s_n;
        if(a < 0 || a >=150) 
            error ("Bad age!");
        age = a;
    }

    string get_first_name()  { return first_name; }
    string get_second_name() { return second_name; }
    int get_age()     { return age;  }
private:
    string first_name, second_name;
    int age;

};

//-------------------------------------------------------------

istream& operator>>(istream& is, Person& p) {
    string f_n, s_n;
    int a;
    cout <<"Enter first name and second name and age:";
    if(!(is >> f_n >> s_n >> a))
        error("Can't read the object");
    Person pp(f_n,s_n,a);
    p = pp;
    return is;
}

//-------------------------------------------------------

ostream& operator<<(ostream& os, Person& p) {

    if(!(os << p.get_first_name() <<' '<< p.get_second_name() << p.get_age()))
        error("Can't write the object");
    return os;
}

//------------------------------------------------------

int main() try
{
    Person p("Goofy","tom",53);
    vector <Person> vp;
    for(int i=0; i<5; i++) {
        cin>>p;
        vp.push_back(p);
    }

    for(int i=0; i<vp.size(); i++)
        cout << vp[i] << endl;

    return 0;
}

catch(exception& e) {
    cerr << e.what();
    return 0;
}
catch(...) {
    return 1;
}

错误与int main()后的第2行(Person p("Goofy","tom",53);)有关,但我不知道为什么strings会出错!

这是错误:http://i59.tinypic.com/v487sw.png

3 个答案:

答案 0 :(得分:5)

i<f_n.size() || i<s_n.size()

应该是

i<f_n.size() && i<s_n.size()

否则你的其中一个字符串超出范围。例如,如果f_n的长度为3,而s_n的长度为5 3 < 3 || 3 < 5将评估为true,并且您将指出f_n[3]超出界限。

P.S:实际上虽然您可能想要将检查提取到一个函数并分别在两个字符串上循环,否则两个字符串中最长的字符串将无法完全检查。

答案 1 :(得分:0)

您需要单独验证f_ns_n,否则只有长度相同才有效。

这看起来像是“学习如何将事物分成函数”练习,所以这样的事情可能是:

bool valid_character(c)
{
   // return true if c is a valid character, false otherwise.
}

bool valid_name(string name)
{
   // true if all the characters in name are valid.
}

Person(string f_n, string s_n, int a)
{
   if (!valid_name(f_n))
   {
      error("Bad first name");
   }
   if (!valid_name(s_name))
   {
      error("Bad second name");
   }

   if(a < 0 || a >=150) 
   {
       error ("Bad age!");
   }

   first_name = f_n;
   second_name = s_n;
   age = a;
}

有些部分留作练习。

答案 2 :(得分:0)

在构造函数中,您要检查f_n和s_n是否包含任何“坏”字符,如果您确定它们具有相同的长度,则无法在一个循环中检查它们。 所以,我建议你分别检查f_n和s_n。 一世

<小时/>

此外, if((f_n [i]&gt;&#39; a&#39;&amp;&amp; f_n [i]&lt;&#39; z&#39;)||(f_n [i]&gt;&#39; A& #39;&amp;&amp; f_n [i]&lt;&#39; Z&#39;)) 通过这样做,你可以确保f_n [i]是一个很好的角色,可能,(我真的不知道你的意思是什么&#39;糟糕的角色& #39;和#39;良好的角色&#39;。)

祝你好运!