C++ 从输入缓冲区问题中丢弃剩余的换行符

标签 c++ newline do-while

我正在尝试为 C++ 类完成这项作业。我遇到了 do/while 循环无法正常工作的问题,有人建议添加行 cin.ignore(2,'\n');在用户要求输入学生姓名的 InputData 函数中。那行得通并且 do/while 现在正在工作。但是,我不是 100% 确定 cin.ignore(2,'\n');有效,我在第一次绕过时遇到问题,用户输入的“名称”的前两个字符被丢弃。如果我将 2 更改为 0,它不会截断姓名的前两个字符,但如果用户输入“y”,他们想继续,程序会跳过第一个问题“输入学生姓名".

非常感谢任何帮助!!

仅供引用,我对一般的编程非常陌生,尤其是 C++。请保持友善,哈哈。

#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;

class Student {
public:
   Student();
   ~Student();
   // Input all info of user
   void InputData();
   // Output class list
   void OutputData();
   // Reset class list
   void ResetClasses();
   Student& operator =(const Student& rightSide);

private:
    string name;
    string stuName;
    int numbClasses;
    string *classList;
};//end student class

//Initialize variables to empty and array to NULL
Student::Student() {
    numbClasses = 0;
    classList = NULL;
    name = "";
}//end variable initialization

//Frees up any memory allocated to array.
Student::~Student() {
    if (classList != NULL) {
    delete [ ] classList;
}//end if
}//end free memory

//Delete the class list
void Student::ResetClasses() {
    if (classList != NULL) {
       delete [] classList;
       classList = NULL;
    }//end if block
    numbClasses = 0;
}//end reset classes

这里是行 cin.ignore(2,'\n');位于

// Inputs info from user.
void Student::InputData() {

int i;
// Reset the class list in case method is called again and array isn't cleared
ResetClasses();

cout << "Enter student name." << endl;
//Discards the leftover newline from input buffer
cin.ignore(2,'\n');
getline(cin, name);


cout << "Enter number of classes." << endl;
cin >> numbClasses;
//Discards the leftover newline from input buffer
cin.ignore(2,'\n');
if (numbClasses > 0) {
    // Construct array big enough to hold # of classes
    classList = new string[numbClasses];
    // Loop through the # classes, input name of each one into array
    for (i = 0; i < numbClasses; i++) {
        cout << "Enter name of class " << (i+1) << endl;
        getline(cin, classList[i]);
    }//end for loop
}//end if block
cout << endl;
}//end input data

输出数据

//Output info entered by user.
void Student::OutputData() {

int i;
cout << "Name: " << name << endl;
cout << "Number of classes: " << numbClasses << endl;
for (i=0; i<numbClasses; i++) {
    cout << "  Class " << (i+1) << ":" << classList[i] << endl;
}//end for loop
cout << endl;
}//end Output data

//overload this operator so there aren't two references to same class list.
Student& Student::operator =(const Student& rightSide) {

int i;
// Erase list of classes
ResetClasses();
name = rightSide.name;
numbClasses = rightSide.numbClasses;

// Copy the list of classes
if (numbClasses > 0) {
    classList = new string[numbClasses];
    for (i=0; i<numbClasses; i++) {
        classList[i] = rightSide.classList[i];
    }//end for loop
}//end if block
return *this;
}//end overload

Main,do/while 循环所在的地方。

// main function
int main() {

    char choice;
    //Do/While loop to ask user if they'd like to continue or end program.
do {
    // Test code with two student classes
    Student s1, s2;
    // Input for s1
    s1.InputData();
    cout << "Student 1's data:" << endl;
    // Output for s1
    s1.OutputData();
    cout << endl;

    s2 = s1;
    cout << "Student 2's info after assignment from student 1:" << endl;
    // Should output same info as student 1
    s2.OutputData();

    s1.ResetClasses();
    cout << "Student 1's info after the reset:" << endl;
    // Should have no classes
    s1.OutputData();

    cout << "Student 2's info, should still have original classes:" << endl;
    // Should still have original classes
    s2.OutputData();
    cout << endl;

    cout << "Would you like to continue? y/n" << endl;
    cin >> choice;

} while(choice == 'y'); //end do/while
return 0;
}//end main

最佳答案

我建议您删除所有 cin.ignore(2,'\n'); 语句,而是在您使用前立即跳过空格(空格和回车) std::getline()。您可以使用 std::ws 操纵器执行此操作:参见: std::ws

因此您的 std::getline() 语句变为:

getline(cin >> std::ws, name); // NOTE: >> std::ws skips whitespace

像这样:

// Inputs info from user.
void Student::InputData() {

int i;
// Reset the class list in case method is called again and array isn't cleared
ResetClasses();

cout << "Enter student name." << endl;
//Discards the leftover newline from input buffer
//cin.ignore(2,'\n');
getline(cin >> std::ws, name); // NOTE: >> std::ws skips whitespace

cout << "Enter number of classes." << endl;
cin >> numbClasses;
//Discards the leftover newline from input buffer
//cin.ignore(2,'\n');
if (numbClasses > 0) {
    // Construct array big enough to hold # of classes
    classList = new string[numbClasses];
    // Loop through the # classes, input name of each one into array
    for (i = 0; i < numbClasses; i++) {
        cout << "Enter name of class " << (i+1) << endl;
        getline(cin >> std::ws, classList[i]); // NOTE: >> std::ws skips whitespace
    }//end for loop
}//end if block
cout << endl;
}//end input data

关于C++ 从输入缓冲区问题中丢弃剩余的换行符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26111698/

相关文章:

来自子类型的 C++ 模板特化

java - 写入文件的字符串不保留换行符

java - 做而行不通

c++ - 在 C++ 文件中包含 Objective-C 头文件

c++ - 将多个数组传递给一个函数

c++ - C++ 的自动代码风格指南测试

渲染新行的 HTML 规范?

windows - 如何让 Git 在索引中存储 CRLF

javascript - 将 for 循环和 while 循环转换为 do...while 循环 JavaScript

c - 帮助使用 C 中的 do/while 和 switch 语句