这是一个家庭作业问题,但我已经完成了它,这更多只是为了我的理解。补充一点,我无法使用 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);
}
如果你不向我们展示一个完整的示例(代码和输入),我们无法告诉你为什么"当你将每个传递给存储它的函数时"事情不起作用:你期望发生什么,你看到了什么。我们也无法告诉您为什么结果与"您提到的第一个代码"不同,如果您也不向我们展示该代码。