cin.ignore(), cin.ignore(1, ' ') 和 scanf(" ”)

问题描述 投票:0回答:1

我有这个任务。如果我使用

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(运行时错误)

c++ class oop scanf cin
1个回答
0
投票

我真的不明白你为什么要使用

ignore
。如果没有计数,它将跳到下一个
\n
,无论有多少个字符。通过计数,它最多会跳过多个字符。因此,在
std::getline
(从 Stream_ 中删除
'\n'
)之后,它将完全跳过下一行而不进行计数,并且将跳过带有计数的行的初始字符。 (如果
scanf
变体是
'\n'
,它将跳过下一个字符,否则设置错误状态。)一般情况下,您可能希望跳过初始空白 (
input >> ws
)——如果流中的下一个字符不是空格(包括
'\n'
),但由于输入是面向行的,我会采纳其他人的建议:仅使用
std::getline
从文件中提取数据,并且解析每一行。

此外,您确实应该在每次

std::getline
之后检查流的状态,以确保它已正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.