鱼C论坛

 找回密码
 立即注册
查看: 1870|回复: 6

求助这个功能怎么实现呀!

[复制链接]
发表于 2023-6-12 22:19:02 | 显示全部楼层
在你的代码中,你尝试使用  std::stringstream  对象来接受用户输入,然后再将它的缓冲区设置为  std::cin  的缓冲区。虽然这样做确实可能在某些情况下起作用,但它可能并不适用于你的特定情况,因为这种方法可能会导致某些异常行为,如你所描述的。

另外,当你的代码中出现 "输入错误请重试!" 这样的提示时,你可以检查  std::cin.good()  的返回值。这是因为你使用了  while  循环来检查输入的合法性,但是  std::cin.good()  可能在遇到错误的输入时返回  false 。这可能就是为什么你看到无限循环的原因。

关于你的问题,如果你想要实现的功能是如果用户输入 "Return",则程序返回,而不是继续,那么你可以在获取用户输入并转化为  std::string  后直接检查它是否等于 "Return",如果是则返回,否则继续程序。

我做了一些小修改,使用  std::istringstream  对象而不是修改  std::cin  的缓冲区,并假设  book  对象的输入运算符已经正确重载。

  1. void LibraryManager::Add_book(book **q) {
  2.     char m;
  3.     std::cout << "请按照如下顺序输入图书信息, 如要返回请输入"Return"! " << std::endl;

  4.     book *p;
  5.     p = new book;

  6.     std::cout << "本书登录号 本书书籍名称 本书作者姓名 本书分类号 本书出版单位 本书出版时间 本书书籍价格" << std::endl;
  7.    
  8.     std::string userInput;
  9.     std::getline(std::cin, userInput);

  10.     if (userInput == "Return") {
  11.         std::cout << "正在返回到菜单,请勿操作" << std::endl;
  12.         Sleep(1500);
  13.         system("cls");
  14.         Menu();
  15.         exit(EXIT_SUCCESS);
  16.     }
  17.     else {
  18.         std::istringstream iss(userInput);
  19.         iss >> *p;

  20.         if (*q == NULL) {
  21.             p->next = NULL;
  22.             *q = p;
  23.         }
  24.         else {
  25.             p->next = NULL;
  26.             (zbook)->next = p;
  27.         }

  28.         zbook = p;
  29.         std::cout << "添加成功,是否继续添加:是Y,否N:" << std::endl;
  30.         std::cin.clear();
  31.         std::cin.ignore(1024, '\n');
  32.         std::cin >> m;

  33.         while ((m != 'Y' && m != 'y' && m != 'N' && m != 'n') || !std::cin) {
  34.             std::cout << "输入错误,请重新输入:" << std::endl;
  35.             std::cin.clear();
  36.             std::cin.ignore(1024, '\n');
  37.             std::cin >> m;
  38.         }

  39.         if (m == 'Y' || m == 'y') {
  40.             Add_book(&abook);
  41.             exit(EXIT_SUCCESS);
  42.         }
  43.         else if (m == 'N' || m == 'n') {
  44.             std::cout << "正在返回到菜单,请勿操作" << std::endl;
  45.             Sleep(1500);
  46.             system("cls");
  47.             Menu();
  48.             exit(EXIT_SUCCESS);
  49.         }
  50.     }
  51. }
复制代码


注意: 你需要确保  book  对象的输入运算符已经正确重载,以支持从  std::istringstream  对象中读取数据。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-12 23:15:23 | 显示全部楼层
铭凡 发表于 2023-6-12 23:11
还是不行
执行结果如下:

看起来问题可能在于你的  book  类对输入流的处理方式。这可能是因为你的  operator>>  实现不适用于从空白字符(例如空格)分隔的字符串流中读取。

为了解决这个问题,你需要确保你的  book  类可以正确地从  std::istringstream  对象中读取。如果你的  book  类的输入运算符已经适当地重载,那么你应该可以像这样处理它:

  1. std::istringstream iss(userInput);
  2. iss >> p->login_number >> p->book_name >> p->author_name >> p->classification_number >> p->publisher >> p->publish_date >> p->book_price;
复制代码


注意,上面的代码假设你的  book  类有如下的数据成员: login_number ,  book_name ,  author_name ,  classification_number ,  publisher ,  publish_date ,  book_price 。你需要根据你的  book  类的实际情况进行调整。

如果你的  book  类的  operator>>  重载是正确的,那么你应该可以直接使用  iss >> *p 。如果不行,你就需要检查你的  operator>>  实现,确保它能正确处理从空格分隔的字符串流中读取。

另外,你的  while  循环条件可能也需要修改。在  std::cin  发生错误(例如输入不是 'Y', 'y', 'N', 'n' 的字符)时,你需要清空缓冲区并忽略剩余的输入,然后再尝试读取。你可以尝试如下的循环:

  1. do {
  2.     std::cin >> m;
  3.     if (m != 'Y' && m != 'y' && m != 'N' && m != 'n') {
  4.         std::cout << "输入错误,请重新输入:" << std::endl;
  5.         std::cin.clear();
  6.         std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
  7.     }
  8. } while (m != 'Y' && m != 'y' && m != 'N' && m != 'n');
复制代码


在这个循环中,如果输入的不是 'Y', 'y', 'N', 'n' 中的一个,那么会清空输入流并忽略剩余的输入,然后提示用户重新输入。当输入正确时,循环才会结束。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-12 23:38:55 | 显示全部楼层
铭凡 发表于 2023-6-12 23:29
你好,按照你的思路,我改了一下,代码如下

非常抱歉给你带来了困扰。针对你提出的问题,我给出以下建议:

1. 我怀疑你的输入可能被某处的 '\n' (换行符)捕获了,因此当你试图使用  std::getline(std::cin, userInput);  时,它立即返回了空字符串。你可以试着在该句之前添加  std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); ,看看是否有所帮助。

2. 我建议你试试直接使用  iss >> *p; ,但是确保你的  operator>>  重载可以从空格分隔的字符串流中正确读取。在你的  book  类中应该有一个类似于以下的方法:

  1. friend std::istream& operator>>(std::istream& in, book& b) {
  2.     in >> b.book_Entry_number >> b.book_name >> b.author_name >> b.book_number >> b.publish_address >> b.publish_time >> b.book_price;
  3.     return in;
  4. }
复制代码


这样就可以直接使用  iss >> *p;  了。如果你的  book  类中并没有这样的方法,或者该方法的实现不正确,那么你就需要使用你之前的方式,即  iss >> p->book_Entry_number >> p->book_name >> p->author_name >> p->book_number >> b.publish_address >> b.publish_time >> b.book_price; 。

3. 对于  std::numeric_limits<std::streamsize>::max()  未定义的问题,你需要在文件顶部加入  #include <limits> ,这样  std::numeric_limits  才可以使用。如果你的编译器仍然提示错误,你可以尝试使用  std::cin.ignore(1024, '\n');  作为替代。

希望这些建议能帮到你!如果还有问题,请随时向我提问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-10-31 04:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表