我有这个任务。如果我使用
cin.ignore()
,结果为 false,而 cin.ignore(1, '\n')
和 scanf("\n")
,结果为 true。我不知道为什么我会失败。请帮助我
本次作业:
编写一个程序来声明一个班级 SinhVien(学生),其中包含以下信息:学生 ID、全名、班级和 GPA(浮点数)。构造函数没有参数,并为属性分配默认值(空字符串,0)。
程序必须使用流运算符通过 cin 和 cout 输入和输出学生对象。
程序必须从键盘读取N个学生的信息(没有学生证)。然后,程序必须按 GPA 降序对学生进行排序,并在屏幕上打印出学生列表,每个学生打印一行。
学生证是按照添加代码B20DCCN后跟从001开始自动递增的整数值(最大为099)的规则自动生成的。对全名进行处理以使其达到标准形式。出生日期标准化为 dd/mm/yyyy 格式
输入:
第一行包含学生人数 N (0 < N < 50).
每个学生分 4 行记录,分别为全名、班级、出生日期和 GPA。
其中:
全名不超过30个字符。 课程采用 PTIT 通常使用的正确格式 出生日期包含足够的日、月、年 3 个部分,但格式可能不正确 dd/mm/yyyy。 GPA 保证在 4 分制范围内,小数点后最多 2 位。 该数据确保没有两个学生具有相同的 GPA。
输出:
打印出已按 GPA 降序排列的完整学号、全名、班级、出生日期(标准化)、GPA(小数点后 2 位)的学生名单。
我的代码:
#include <iostream>
#include <sstream>
#include <algorithm>
#include <string>
#include <iomanip>
using namespace std;
std::string so(int k)
{
std::string st = std::to_string(k);
if (st.length() == 1)
st = "0" + st;
return st;
}
class SinhVien
{
private:
public:
static int dem;
float gpa;
std::string code, name, grade, date;
friend std::istream &operator>>(std::istream &input, SinhVien &object)
{
object.code = "B20DCCN0" + so(++dem);
// input.ignore();
input.ignore(1, '\n');
/* if (dem == 1)
scanf("\n");
else input.ignore(); */
auto formatName = [](std::string &st)
{
std::stringstream sst(st);
std::string temp;
st = "";
while (sst >> temp)
{
for (char &c : temp)
if (isupper(c))
c = tolower(c);
temp[0] = toupper(temp[0]);
st += temp + " ";
}
st.pop_back();
};
std::getline(input, object.name);
formatName(object.name);
std::getline(input, object.grade);
auto formatDate = [](std::string &st)
{
if (st[2] != '/')
st = "0" + st;
if (st[5] != '/')
st.insert(3, "0");
};
std::getline(input, object.date);
formatDate(object.date);
input >> object.gpa;
return input;
}
friend std::ostream &operator<<(std::ostream &output, SinhVien object)
{
output << object.code << " " << object.name << " " << object.grade << " " << object.date << " " << std::fixed << std::setprecision(2) << object.gpa << std::endl;
return output;
}
};
int SinhVien::dem = 0;
void sapxep(SinhVien a[], int n)
{
auto compare = [](SinhVien a, SinhVien b) -> bool
{
return a.gpa > b.gpa;
};
std::sort(a, a + n, compare);
}
int main()
{
SinhVien ds[50];
int N, i;
cin >> N;
for (i = 0; i < N; i++)
{
cin >> ds[i];
}
sapxep(ds, N);
for (i = 0; i < N; i++)
{
cout << ds[i];
}
return 0;
}
如果我使用
cin.ingore()
,我的程序是RTE(运行时错误)
我真的不明白你为什么要使用
ignore
。如果没有计数,它将跳到下一个\n
,无论有多少个字符。通过计数,它最多会跳过多个字符。因此,在 std::getline
(从 Stream_ 中删除 '\n'
)之后,它将完全跳过下一行而不进行计数,并且将跳过带有计数的行的初始字符。 (如果 scanf
变体是 '\n'
,它将跳过下一个字符,否则设置错误状态。)一般情况下,您可能希望跳过初始空白 (input >> ws
)——如果流中的下一个字符不是空格(包括 '\n'
),但由于输入是面向行的,我会采纳其他人的建议:仅使用 std::getline
从文件中提取数据,并且解析每一行。
此外,您确实应该在每次
std::getline
之后检查流的状态,以确保它已正常工作。