用于操作每个令牌的字符串分析(无 STL)



这是一个家庭作业问题,但我已经完成了它,这更多只是为了我的理解。补充一点,我无法使用 STL

:(

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

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

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;
    }

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

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

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

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);
}
如果你

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

最新更新