#include <string>
#include <iostream>
#include <iomanip>
using namespace std;
void add(string names[], int section[], int grade[]);
void printRecords(const string names[], const int sections[], const int grades[], int size);
void insertionSort(int numbers[], int size);
void display(const int numbers[], int size);
int main(){
//command
string command;
//add
string names[20] = { "" };
int sections[20];
int grades[20];
cout << "Enter a command (add, print, drop, sort, average, quit):\n";
cin >> command;
while (command != "quit"){
if (command == "add"){
add(names,sections, grades);
}
else if (command == "print"){
printRecords(names, sections, grades, 20);
}
else if (command == "drop"){
cout << command;
}
else if (command == "sort"){
cout << command;
}
else if (command == "average"){
cout << command;
}
else if (command == "smallest"){
cout << command;
}
else{
cout << "Invalid command.\n";
}
cin >> command;
}
cout << "Quitting the program.\n";
return 0;
}
void printRecords(const string names[], const int sections[], const int grades[], int size) {
int i;
for (i = 0; i < size; i = i + 1) {
cout << "[" << i << "]:\t";
cout << setw(20) << left << names[i];
cout << setw(5) << sections[i];
cout << setw(10) << grades[i];
cout << "\n";
}
return;
}
void insertionSort(int numbers[], int size) {
int i;
int j;
int toInsert;
// outer loop i is the element we are to insert in to the sorted portion.
// [0, i-1] is the sorted range.
for (i = 1; i < size; i = i + 1) {
toInsert = numbers[i];
j = i - 1;
while (j >= 0 && numbers[j] > toInsert) {
numbers[j + 1] = numbers[j];
j = j - 1;
}
// either j >= 0 and numbers[j] <= toInsert
// or j = -1 here
// we want to store toInsert at numbers[j+1]
numbers[j + 1] = toInsert;
}
return;
}
void add(string names[], int sections[], int grades[]){
int i = 0;
while (names[i] != "" && i < 20){
i = i + 1;
}
cin >> names[i];
cin >> sections[i];
cin >> grades[i];
return;
}
我只需要用户在调用函数时只输入一组新信息。 添加功能是我最关心的。为什么它无休止地砍掉?
假设在最后一个记录之后添加一个学生的记录(姓名,部分和成绩) 当前的电子表格。您的电子表格应该能够容纳20个学生记录。如果 目前已经有20学生档案,你的代码应该提示“电子表格已满。能够 未添加“。
答案 0 :(得分:0)
将cin >> command
更改为getline(cin, command)
。
答案 1 :(得分:0)
在这里,这应该解决它。究竟发生了什么正是Chnossos所怀疑的。当cin >>
输入缓冲区没有清除换行符时,除非你调用cin.ignore()忽略它。但是,如果没有换行符,你将最终等待它,让你输入额外的输入来实现目标。
现在,getline(cin, var)
使用换行符,因此在使用此函数后您无需忽略,否则您还将等待更多数据。
我没有把它看得太厉害,但是我编写了这个并且它正在工作,因此我相信你只是得到了太多的新行而且消耗不够,因此它看起来像是一个无限循环。
有更多有说服力的方法可以做到这一点,但基本要点是使用getline()
字符串,对于其他类型,如果之后使用cin >>
,则可以继续使用cin.ignore()
。
我建议你多看一下。这是代码。
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;
void add(string names[], int section[], int grade[]);
void printRecords(const string names[], const int sections[], const int grades[], int size);
void insertionSort(int numbers[], int size);
void display(const int numbers[], int size);
int main(){
//command
string command;
//add
string names[20] = { "" };
int sections[20];
int grades[20];
cout << "Enter a command (add, print, drop, sort, average, quit):\n";
getline(cin, command);
while (command != "quit"){
if (command == "add"){
add(names,sections, grades);
}
else if (command == "print"){
printRecords(names, sections, grades, 20);
}
else if (command == "drop"){
cout << command;
}
else if (command == "sort"){
cout << command;
}
else if (command == "average"){
cout << command;
}
else if (command == "smallest"){
cout << command;
}
else{
cout << "Invalid command.\n";
}
getline(cin, command);
}
cout << "Quitting the program.\n";
return 0;
}
void printRecords(const string names[], const int sections[], const int grades[], int size) {
int i;
for (i = 0; i < size; i = i + 1) {
cout << "[" << i << "]:\t";
cout << setw(20) << left << names[i];
cout << setw(5) << sections[i];
cout << setw(10) << grades[i];
cout << "\n";
}
return;
}
void insertionSort(int numbers[], int size) {
int i;
int j;
int toInsert;
// outer loop i is the element we are to insert in to the sorted portion.
// [0, i-1] is the sorted range.
for (i = 1; i < size; i = i + 1) {
toInsert = numbers[i];
j = i - 1;
while (j >= 0 && numbers[j] > toInsert) {
numbers[j + 1] = numbers[j];
j = j - 1;
}
// either j >= 0 and numbers[j] <= toInsert
// or j = -1 here
// we want to store toInsert at numbers[j+1]
numbers[j + 1] = toInsert;
}
return;
}
void add(string names[], int sections[], int grades[]){
int i = 0;
while (names[i] != "" && i < 20){
i = i + 1;
}
getline(cin, names[i]);
cin >> sections[i];
cin.ignore();
cin >> grades[i];
cin.ignore();
return;
}
答案 2 :(得分:0)
问题是如果你试图读入一个整数,例如cin >> sections[i];
,但您输入的数字不是,但此操作失败,cin
进入失败状态。
之后,cin
仍处于失败状态,直到您通过执行cin.clear()
取消该状态。此操作也不会从流中删除问题字符,因此您通常希望将clear()
与另一个读取操作组合以读取和丢弃问题字符。
如果您只在程序需要整数时输入整数,那么您的代码将无法循环#34;。显然你在预期整数时输入了单词。
要解决此问题,有两件事要做。首先,总是测试输入函数是否失败。完成cin >> command;
后,也可以:
if ( !cin )
{
break; // exit instead of infinitely looping
}
但是一旦发生故障状态就很快就能检测出来。在add
函数内,在最后cin
之后,您应该执行:
if ( !cin )
{
cout << "Invalid input entered - discarding entry\n";
names[i] = "";
cin.clear();
string junk;
getline(cin, junk);
}
(还有其他方法可以忽略垃圾,但我认为这个很容易理解)。
最后,add
函数使用格式化提取(即>>
),因此无法判断此人是否按Enter键。如果你想让它们按Enter键意味着他们已经完成输入当前条目(并且要丢弃无效条目),那么你需要使用std::getline
来存储整行一个字符串,然后使用stringstream
从该行进行格式化提取。
例如,add
函数可以是:
void add(string names[], int sections[], int grades[])
{
int i = 0;
while (names[i] != "" && i < 20){
i = i + 1;
if ( i == 20 )
return;
string line;
getline(cin, line);
istringstream iss(line);
iss >> names[i] >> sections[i] >> grades[i];
if ( !iss )
{
names[i] = "";
cerr << "Invalid entry ignored.\n";
}
}
您可能需要#include <sstream>
。请注意,在这个版本中你不需要丢弃&#34;垃圾&#34;,因为垃圾是在串流中被破坏的。
根据经验,如果您要混合字符串和整数输入,那么使用getline
加stringstream
将使您的程序更加用户友好。