0

这是一个家庭作业问题,但我已经完成了,这只是为了我的理解。补充一下,我不能使用 STL :(

基本上,我们要实现一个“学生”类,它有 5 个参数(名字/姓氏、ID、年级和专业)。然后每个学生对象必须存储在一个数组中(我们称之为教室)。

当用户添加新学生时,我的问题就出现了。起初我的代码只是像这样获取每个参数:

cin >> first >> last >> id >> grade >> major;

然后将它们传递给另一个将其存储在数组中的函数。如果用户按应有的方式输入所有内容,这可以正常工作,例如输入:

students> add John Smith 123 Freshman Computerscience

但是当输入不正确时,特别是使用 ID 输入(它是一个 int),如下所示:

students> add John Smith 123abc Freshman Computerscience

它将以“abc”作为成绩,以“新生”作为专业,其余的都会出现错误。

所以我决定将整个输入作为一个字符串解析出来,代码如下:

    class Student {
    private:
        string first_name;
        string last_name;
        int ID;
        string classification;
        string major;
    public:
        Student();

        /* Main class functions */
        void add(string, string, int, string, string);
        void print(string);
        bool remove(int);

        /* Helper class functions */
        bool empty();
        bool ifexist(int);
    };

  int main() 
     {
        bool done = false;
        string command, first, last, grade, major;
        int id;
        string query, input;
        string inputArray[6];
        string token = " ";
        while(!done) {
            cout << prompt;
            cin >> command;

            if(command == "add")
            {
                /* Get new student info */
                cin >> first >> last >> id >> grade >> major;;

                // this commented code is my attempt to fix error
                // count = 0;
                // while(getline(cin, input)) {
                //  stringstream s(input);
                //  while(s >> token) {
                //      inputArray[count] = token;
                //      count++;
                //  }
                //  if(count == 5) break;
                // }

                // first = inputArray[0];
                // last  = inputArray[1];
                // if(atoi(inputArray[2].c_str()))
                //  id= atoi(inputArray[2].c_str());
                // else cout << ERROR_INPUT << endl; 
                // grade = inputArray[3];
                // major = inputArray[4];

                // for (int i=0; i<5; i++) {
                //  cout << inputArray[i] << endl;
                // }
                //cout << first << endl << last << endl << id << endl << grade << endl << major << endl;

                int i = getInsertPoint();
                bool e = ifexist(id);

                /* Check if student already exists */
                if(e) cout << "Error! Already exists, try again" << endl;
                else  classroom[i].add(first, last, id, grade, major); 
            }
            else if(command == "print") 
            {
                /* Get query type to be printed (ex: firstname) */
                cin >> query;
                print(query);
            }
            else if(command == "remove")
            {
                cin >> id;
                remove(id);
            }
            else if(command == "quit") done = true;
            else cout << ERROR_INPUT << endl;
        }
        return 0;
    }

我可以打印出数组,一切都很好,但是当我将每个数组传递给将它存储在对象中的函数时,什么也没有出现。但是,当我使用我提到的第一个代码时,它确实有效。

所以我的问题是:有没有更好的方法来解析/检查输入字符串(不带 STL),允许我将每个令牌单独发送到另一个函数?

4

1 回答 1

0

您的循环结构有些损坏。根据您的意图,这可能是一个问题:

while(getline(cin, input)) {
    stringstream s(input);
    while(s >> token) {
      inputArray[count] = token;
      count++;

在这里,您将愉快地继续,即使您累积的单词超过了您的数组可以处理的 6 个单词。如果发生这种情况,程序的行为将变得不确定。

    }
    if(count == 5) break; //got everything I need

因此,如果您恰好累积了 5 个单词(您的数组可以容纳的 6 个单词),您将处理这五个单词。如果少于 5 个单词,则从下一行继续累积额外的单词。只有在“解析”一个或多个(最多 5 个)非空行产生正好 5 个单词时,您才会停止。如果您超过了 5 个字的限制(例如,如果第一行有 4 个字,第二行至少有 2 个字),您将继续直到输入结束或程序崩溃,因为您正在写满内存。

  }

您的使用atoi()将接受无效输入(如“123abc”)。另一方面,当空间意外丢失时(“123Freshman”),您的代码将出现异常。

所以我对你的问题的回答是:是的,有更好的方法来解析和检查输入。但除非您能清楚地说明输入规则,否则我们无法帮助您修复代码。当您询问“将每个令牌单独发送到另一个功能”的方法时,您的意思也不清楚。

逐字逐句,答案将是:

string token;
while (getline(cin, token)) { 
   another_function(token);
}

如果您不向我们展示一个完整的示例(代码和输入),我们无法告诉您为什么“当 [您] 将每个传递给将其存储在对象中的函数时”事情不起作用:您期望什么发生,你所看到的。如果您也不向我们展示该代码,我们也无法告诉您为什么结果与“[您]提到的第一个代码。”不同。

于 2013-01-31T23:52:53.867 回答