在C中,输入输出用scanf和printf,在输入数据的同时还需说明数据的类型,如果输入数据较多,那就很麻烦,而C++中也有相似的东西cin和cout,它们来自C++的一个名叫" iostream"的类库。

iostream是由istream(输入流)和ostream(输出流)派生.所以在iostream中就有了输入和输出的相关对象:
1、cin 表示标准输入(standard input)的istream类对象,cin使我们可以从设备读取数据。

2、cout 表示标准输出(standard output)的ostream类对象。对应于标准输出流,默认情况下是显示器。这是一个被缓冲的输出,可以被重定向。

3、cerr 对应标准错误流,用于显示错误消息。默认情况下被关联到标准输出流,但它不被缓冲,也就说错误消息可以直接发送到显示器,而无需等到缓冲区或者新的换行符时,才被显示。一般情况下不被重定向。

cout与cerr的区别:cout的输出可以重定向到一个文件中,而cerr必须输出在显示器上。

暂时先介绍那么多,以下主要介绍cin.get()、cin.getline()、cin.clear()、cin.sync()等的用法。

首先看看cin.get(),它是一个读取单个字符的方法。字符变量=cin.get(),相当于cin.get(字符变量)。

例一:

#include
using namespace std;

int main()
{
  char cstr;
  cstr = cin.get(); //读取单个字符,在屏幕输入,相当于cin.get(cstr);
  cout<<cstr<<endl; //输出刚刚载入的单个字符
  system("pause");  //进行暂停,否则会一闪而过

}

运行程序后

输入:a 输出:a

但当输入的为多个英文字符时,那又会如何呢?

输入:abcd 输出:a

结论:cin.get()只能读取第一个字符

例二:

#include
using namespace std;

int main()

{
  char str1;
  char str2;
  str1 = cin.get(); //读取单个字符,在屏幕输入
  str2 = cin.get();
  cout<<str1<<<<str2<<endl; //输出刚刚载入的单个字符
  system("pause");  //进行暂停,否则会一闪而过
}

运行程序后

输入:abcd 输出:ab
既然cin.get()是读取第一个字符,那str2为什么不也是a呢?
原理如下:
    在cin这个对象里,有一个储存字符的流,可以想象成缓冲区,事实上是cin里封装的一个东西.当我们在程序上输入字符后,对象cin获得了我们输入的字符。例如获得abcd,然后再通过.get()把流里面的第一个字符去掉,赋给str1,这时,cin里储存的流的数据为bcd,而str1则获得了a。当我们再次运行str2 = cin.get()时,同理把cin里流的数据的b拿出来给了str2,此后,cin里面的流的数据为cd,而str2则为b,所以最后输出时,便能输出ab了。

还有个补充,究竟什么时候才输入数据呢?我们可以再通过上面的代码进行尝试,我们输入单个字母'a',然后按回车,发现并没有输出数据,而是再等待一次输入数据,我们再输入字母'b',按回车后便输出ab了。相信到这里,大家都应该明白了,因为当我们第一次输入a后,通过str1 = cin.get()使cin里的流没有数据,清空了。所以到第二次要再赋给str2值时,它找不到数据,要重新再输入数据。由此来看可以知道,当cin里的流数据清空时,便需要重新输入才能赋值。而cin.get()还有个用法:

例三:

#include 
using namespace std;

int main()
{
  char str1;
  char str2;
  str1 = cin.get(); //读取单个字符,在屏幕输入
  cin.get();
  str2 = cin.get();
  cout<<str1<<str2<<endl; //输出刚刚载入的单个字符
  system("pause");
}

运行程序后

输入:abcd 输出:ac

程序中有3个cin.get(),由此可知,当空回调cin.get()时,cin.get便自动在cin中的流数据中删除一个字母,起了一个删除作用。

对cin.get()有了一定了解之后,对cin.getline()的学习就可以更快了,原理是一致的,但是cin.getline()则是获取一整行文本。以下是cin.getline()原形:
getline(char *line,int size,char='/n')
第一个是字符指针,第二个是字符长度,第三个为结束标识符。

例四:

#include 
using namespace std;

int main()
{
  char str[200];
  cin.getline(str, sizeof(str)); //第三个不输入,默认回车为结束标符

cout<<str<<endl;               //输出
  system("pause");
}

这样我们输入多个英文或数字,然后按回车,就会输出刚刚输出的东西了。接下来,我们讨论第三个参数的作用。

例五:

#include 
using namespace std;

int main()
{
  char str[200];
  cin.getline(str, sizeof(str), 'X'); //以单个英文字母'X'作为终止标识符
  cout<<str<<endl; //输出
  system("pause");
}

当我们输入多个数字或者字母时,例如
输入: abcdeX(回车)   输出:abcde

aXbcde              a             
      Xabcde

这样X便成了终止符,如上可知,当遇到第一个结束符标志时,就结束,输出其前面的所有字符。其原理和cin.get()一样.或许我们可以像cin.get()那样尝试一下:

例六:

#include 
using namespace std;

int main()
{
  char str1[200];
  char str2[200];
  cin.getline(str1, sizeof(str1), 'X'); //以单个英文字母'X'作为终止标识符
  cin.getline(str2, sizeof(str2), 'Y'); //以单个英文字母'Y'作为终止标识符
  cout<<"第一行是:"<<str1<<endl; //输出
  cout<<"第二行是:"<<str2<<endl;
  system("pause");
}

输入:abcdXXXefghYYYigkl(回车)

输出: 第一行是:abcd

第二行是:XXefgh

如上可知,当遇到第一个结束符'X'结束输出abcd,之后遇到第一个结束符'Y'结束输出XXefgh。

接下来谈谈cin.clear()的作用,第一次看到这东西,很多人以为就是清空cin里面的数据流,而实际上却与此相差甚远,首先看看以下代码:

例七:

#include
using namespace std;

int main()
{
  int a;
  cin>>a;
  cout<<cin.rdstate()<<endl;
  if(cin.rdstate() == ios::goodbit)
  {
    cout<<"输入数据的类型正确,无错误!"<<endl;
  }
  if(cin.rdstate() == ios_base::failbit)
  {
    cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl;
  } 
  system("pause");
}

我们定义要输入的变量是整型,但如果输入了英文字母或者汉字,那就会发生错误,cin里有个方法能检测这个错误,就是cin.rdstate()。

当cin.rdstate()返回0(即ios::goodbit)时表示无错误,可以继续输入或者操作,若返回2则发生非致命错误即ios::failbit,则不能继续输入或操作。而cin.clear()则可以控制我们此时cin里对这个问题的一个标识。语发如下:
cin.clear(标识符);
标识符号为:

  • goodbit 无错误
  • Eofbit 已到达文件尾
  • failbit 非致命的输入/输出错误,可挽回
  • badbit 致命的输入/输出错误,无法挽回
    若在输入输出类里.需要加ios::标识符号

    通过cin.clear,我们能确认它的内部标识符,如果输入错误则能重新输入。结合真正的清空数据流方法cin.sync(),请看下例:

例八:

#include
using namespace std;

int main()
{
  int a;
  while(true)
 {
    cin>>a;

if(!cin) //条件可改写为cin.fail()
    {
      cout<<"输入类型错误,请重新输入!"<<endl;
      cin.clear(); //复为标志,将cin中的所有标志设置为有效状态

cin.sync(); //清空流
    }
    else
    {
      cout<<a<<endl;
      break;
    }
  }
  system("pause");
}

上面的cin默认值为非0,当输入为非整形时,它的状态标识符改为fail(即0),再用cin.clear()让错误标识改回为非0,可以继续输入,再清空流数据继续输入。如果没有了cin.clear(),则会进入死循环,其过程为我们输入了英文字母,它的状态标识便为fail,当运行到条件判断时,便总是回到错误的条件表示里,并且再也没有办法输入,因为错误的表示关闭了cin,所以会进入死循环。可以分别注释掉cin.clear()和cin.sync()进行验证。

注:
    技术在于交流、沟通,转载请注明出处并保持作品的完整性。

cin详解(cin.get()、cin.getline()、cin.clear()、cin.sync())的更多相关文章

  1. cin详解(get()、getline()、clear()、sync())

    简述 在C中,输入输出用scanf和printf,在输入数据的同时还需说明数据的类型,如果输入数据较多,那就很麻烦,而C++中也有相似的东西cin和cout,它们来自C++的一个名叫" io ...

  2. c++ cin>>详解

    参考地址:http://www.cnblogs.com/A-Song/archive/2012/01/29/2331204.html 程序的输入都建有一个缓冲区,即输入缓冲区.一次输入过程是这样的,当 ...

  3. C++输入cin详解

    输入原理: 程序的输入都建有一个缓冲区,即输入缓冲区.一次输入过程是这样的,当一次键盘输入结束时会将输入的数据存入输入缓冲区,而cin函数直接从输入缓冲区中取数据.正因为cin函数是直接从缓冲区取数据 ...

  4. c++之cin/cin.get/cin.getline()详解

    C++输入过程中,是把输入加载到缓冲区中,然后对缓冲区中的字符进行读取.cin,cin,get(),cin.getline()三个函数虽然都能进行数据读取,但是它们对缓冲区内数据的处理方法是不同的(如 ...

  5. C++学习45 流成员函数put输出单个字符 cin输入流详解 get()函数读入一个字符

    在程序中一般用cout和插入运算符“<<”实现输出,cout流在内存中有相应的缓冲区.有时用户还有特殊的输出要求,例如只输出一个字符.ostream类除了提供上面介绍过的用于格式控制的成员 ...

  6. cin与cout详解

    输入和输出并不是C++语言中的正式组成成分。C和C++本身都没有为输入和输出提供专门的语句结构。输入输出不是由C++本身定义的,而是在编译系统提供的I/O库中定义的。C++的输出和输入是用" ...

  7. c++ cout、<< 、cin、>> 、endl 详解

    std::cout是在#include<iostream>库中的ostream类型中的对象 std::表示命名空间,标准库定义的所有名字都在命名空间std中 std::cout是在#inc ...

  8. 注意当cin.getline、和cin 合用的时候

    1. getline有两种,一个是string的(getline(cin,s)),一个是istream的(cin.getline(s,maxsize,delim)). 2. 当用cin输入了数据后,在 ...

  9. cin.get();cin.clear();cin.sync()

    先看代码: #include<iostream> using namespace std; int main(){ int c,x; cout<<"输入大小" ...

随机推荐

  1. 为什么使用 SLF4J 而不是 Log4J 来做 Java 日志

    转自:为什么使用 SLF4J 而不是 Log4J 来做 Java 日志 英文原文:Why use SLF4J over Log4J for logging in Java 每个Java开发人员都知道日 ...

  2. CSS3背景颜色渐变效果

    1.firefox浏览器: background-image: -moz-linear-gradient(top , #eef9fe, #d1ecff); 2.safari.chrome浏览器: ba ...

  3. jQuery插件实现左右无缝轮播

    前段时间学习jQuery的时候,在网上找了个SuperSlide插件,做轮播图demo,感觉对于新人而言,还是挺容易上手的,代码量也少. 直接贴代码吧. 1.HTML <!DOCTYPE htm ...

  4. java 导出excel(简单案例)

    public class Student { private int id; private String name; private int age; private Date birth; pub ...

  5. IIS7部署MVC站点后,打开无法正常跳转到首页

    产品拿到安装包后想在本地安装测试一下,但是管理工具里没有IIS. 后来在windows功能里添加iis服务. 添加后成功安装. 但是第一次打开时,页面提示要“启用目录浏览”. 启用后,打开的却是站点目 ...

  6. RocketMQ初步应用架构理论

    RocketMQ初步应用架构理论 写给RocketMQ架构应用入门,内容涉及它的设计机理以及推到出来的应用注意事项,入门人员请看. 稍微涉及技术细节,留以我设计中间件时参考,将来整理深度文档时会抽取走 ...

  7. MVC3+EF4.1学习系列(八)-----利用Repository and Unit of Work重构项目

    项目最基础的东西已经结束了,但是现在我们的项目还不健全  不利于测试 重复性代码多   层与层之间耦合性高  不利于扩展等问题.今天的这章 主要就是解决这些问题的.再解决这些问题时,自己也产生了很多疑 ...

  8. LeetCode OJ 88. Merge Sorted Array

    Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note:Yo ...

  9. 2015 ACM/ICPC Asia Regional Shenyang Online

    1001 Traversal 1002 Best Solver 1003 Minimum Cut 类似于POJ 3417的做法. 考虑每条新边对树边的覆盖次数. 每条树边被覆盖的次数其实就是断裂这条树 ...

  10. Python 学习笔记5

    Life is like a box of chocolate. 今天继续学习Python数据结构. http://www.pythondoc.com/pythontutorial3/datastru ...