C++函数二次调用时cin/cout语句合并的问题求助
问题分析与解决方案
你猜得完全没错!这个问题就是输入缓冲区里残留的换行符搞的鬼,我给你拆解清楚:
当你用cin >> year读取年份时,用户输入完年份按下回车,这个回车对应的\n字符会留在输入缓冲区里。等第二次调用enterBookInformation函数时,第一个cin.getline()会直接读取这个残留的换行符,它会认为这是一个空行,所以直接跳过了书名的输入,紧接着就输出了作者的提示,看起来就像是两个提示合并在了一起。
下面给你两种简单有效的解决方法:
方法1:读取年份后清空缓冲区
在cin >> year之后,我们可以用cin.ignore()把缓冲区里剩下的所有字符(包括那个讨厌的换行符)都清空。为了确保不管缓冲区里剩多少内容都能清干净,最好这样写:
std::cin >> year; // 忽略从当前位置到换行符的所有字符,包括换行符本身 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
记得要在代码开头加上<limits>头文件,不然std::numeric_limits会报错。
方法2:统一用getline读取所有输入
如果你不想混用cin >>和getline,可以把年份也当作字符串读取,再转换成整数:
std::cout << "Enter the Year of Publication " << counter << ": "; std::string year_str; std::getline(std::cin, year_str); year = std::stoi(year_str);
这种方法从根源上避免了缓冲区残留的问题,而且如果你用C++的std::string代替C风格的字符数组,代码会更安全简洁(后面会给你提这个建议)。
修改后的完整代码(以方法1为例)
//struct_example.cpp #include <iostream> #include <iomanip> #include <cstring> #include <limits> // 新增头文件,用于处理缓冲区清空 using namespace std; using std::setw; struct books_t enterBookInformation(struct books_t book, unsigned short counter); void printBooks(struct books_t book1, struct books_t book2); struct books_t { char title[50]; char author[50]; int year; }; int main(void) { struct books_t book1; struct books_t book2; book1 = enterBookInformation(book1, 1); book2 = enterBookInformation(book2, 2); printBooks(book1, book2); } struct books_t enterBookInformation(struct books_t book, unsigned short counter) { char title[50], author[50]; int year; std::cout << "Enter Title of Book " << counter << ": "; std::cin.getline(title, sizeof(title)); std::cout << "Enter Author of Book " << counter << ": "; std::cin.getline(author, sizeof(author)); std::cout << "Enter the Year of Publication " << counter << ": "; std::cin >> year; // 清空缓冲区残留的换行符 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); strcpy(book.title, title); strcpy(book.author, author); book.year = year; return book; } void printBooks(struct books_t book1, struct books_t book2) { std::cout << setw(15) << "Book 1 Title: " << setw(25) << book1.title << endl; std::cout << setw(15) << "Book 1 Author: " << setw(25) << book1.author << endl; std::cout << setw(15) << "Book 1 Year: " << setw(25) << book1.year << endl; std::cout << setw(15) << "Book 2 Title: " << setw(25) << book2.title << endl; std::cout << setw(15) << "Book 2 Author: " << setw(25) << book2.author << endl; std::cout << setw(15) << "Book 2 Year: " << setw(25) << book2.year << endl; }
给C转C++的小建议
既然你刚转C++,推荐你尽量用std::string代替C风格的char[],这样不仅能避免strcpy带来的越界风险,处理输入也更省心。比如把结构体改成这样:
struct books_t { std::string title; std::string author; int year; };
之后读取输入直接写成std::getline(std::cin, book.title),不用再手动复制字符串,代码会简洁很多,也更符合C++的风格。
内容的提问来源于stack exchange,提问作者bmw417
相关产品推荐
相关产品推荐

