C++学习笔记(一)——删除错误输入

源程序:C++Primer例题6.14,求5个高尔夫得分的平均数,5个数字依次输入,如果输入非数字,程序将拒绝,并要求用户继续输入数字。

 

#include<iostream>
using namespace std;

const int Max = 5;

int main()
{
  int golf[Max];
  cout << "Please enter your golf scores.\n";
  cout << "You must enter " << Max << " rounds.\n";
  int i;
  for (i = 0; i < Max; i++)
  {
    cout << "round #" << i+1 << ":";
    while(!(cin >> golf[i]))//当输入为空

    {
      cin.clear();//cin.clear()重置cin以接受新的输入
      while(cin.get()!='\n')//如果输入的字符不是回车,那么执行continue,即清除上一次输入最后留在输入流里的回车。
      {
        continue;
      }
      cout << "Please enter a number:";
    }
  }
  double total = 0.0;
  for(i = 0; i < Max; i++)
  {
    total + = golf[i];
  }
  cout << total/Max << " = average score "
  << Max << " rounds\n";

  return 0;
}

 

一、关于cin如何处理输入行

使用cin进行输入时,程序将输入视为一系列的字节,其中,每个字节都被解释为字符编码。不管目标数据类型是什么,输入一开始都是字符数据——文本数据。然后cin对象负责将文本转换为其他类型。

假设有范例输入行:38.5 19.2

1. 当使用char类型进行存储时:
  char ch;

  cin >> ch;

输入行中第一个字符被赋给ch,在这里第一个字符为数字3,其二进制字符编码被存储在变量ch中。输入和目标变量都是字符,因此不需要转换。

注意:这里存储的是字符'3',而不是数字3。

2. 当使用int类型进行存储时:

  int n;

  cin >> n;

在这种情况下,cin将不断读取,直到遇到非数字字符,即,它将读取3和8,遇到'.'时停止读取,这样'.'成为输入队列的下一个字符,cin通过计算发现,这两个字符对应数值38,因此将38的二进制编码复制到变量n中。

3. 当使用double类型进行存储时:

  double x;

  cin >> x;

这种情况下,cin将不断读取,直到遇到第一个不属于浮点数的字符,即,它将读取3、8、'.'、和5,这之后,空格将成为输入队列的下一个字符。cin通过计算发现,这四个字符对应数值38.5,因此将38.5的二进制编码(浮点格式)复制到变量x中。

4. 当使用char数组进行存储时:

  char word[50];

  cin >> word;

这种情况下,cin将不断读取,直到遇到空白字符,即,它将读取3、8、'.'、和5,这之后,空格将成为输入队列的下一个字符。然后,cin将这4个字符的编码存储到数组word中,并在末尾加上一个空字符,这里不需要任何转换。

5. 当使用char数组,但使用cingetline()来接受输入时:

  char word[50];

  cin.getline(word,50);

在这种情况下,cin将不断读取,直到遇到换行符。所有字符都将被存在数组word中,并在末尾加上一个空字符。换行符被丢弃,输入队列中的下一个字符是下一行的第一个字符,这里也不需要任何转换。

 

二、cin.clear()

参考https://blog.csdn.net/weixin_42108411/article/details/104594283

当cin函数输入错误的时候,cin里面有个函数可以自动检测到输入错误,若想继续输入便要清楚掉这个错误。我们可以利用函数cin.rdstate()函数来读取错误的标识符。

返回值有四种:

  0:goodbit 无错误

  1:Eofbit 已达文件尾

  2:failbit 非致命的输入/输出错误,可挽回

  3:badbi 致命的输入/输出错误,无法挽回

如果错误状态不为0时,cin将无法正常执行。

cin.clear()的作用即为清除错误状态,cin.clear()的默认值为0。

三、回到例题代码

存疑段落:

  while(!(cin >> golf[i]))//当输入为空

  {
    cin.clear();//cin.clear()重置cin以接受新的输入
    while(cin.get()!='\n')//如果输入的字符不是回车,那么执行continue,即清除上一次输入最后留在输入流里的回车。
    {
      continue;
    }
    cout << "Please enter a number:";
  }

使用cin.clear()清除错误状态后,cin.get()是读取下一个字符,因为我们输入的最后一个字符为回车,因此,当读到回车的,异常字符已被完全清空。

 

posted @   唐欢忱  阅读(365)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示