(1)cin----标准输入流对象, 与标准输入设备相联系(通常指键盘)。
例如: cin>>变量名;
“>>”为提取运算符(输入运算符),表示从键盘读取数据放入变量中。
(2) cout---标准输出流(流对象), 与标准输出设备相联系(通常指显示器)。
例如: cout<<“数据”;
“<<”为插入运算符(输出运算符),表示将“数据”写到显示器上。
(3) cerr---非缓冲型的标准出错流对象,与标准输出设备相联系(通常指键盘)。
(4) clog---缓冲型的标准出错流,与标准输出设备相联系(通常指显示器)。
cerr与clog均用来输出出错信息。
cerr和clog之间的区别是:
cerr是不经过缓冲区,直接向显示器上输出有关信息,因而发送给它的任何内容都立即输出;
clog中的信息存放在缓冲区中,缓冲区满后或遇上endl时向显示器输出。
只要在程序中包含头文件iostream.h,C++程序开始运行时这四个标准流对象的构造函数都被自动调用。
用户也可以用istream和ostream等类声明自己的流对象.
例如
istream is;
ostream os;
声明了is为输入流对象,声明了os为输出流对象。
输入输出流的成员函数
1.put函数
put函数常用的调用形式为:
cout.put(单字符);
或
cout.put(字符型变量);
功能: 用于输出一个字符
例如:
cout.put('A');
它与语句:cout<<'A'; 等价,将字符A显示在屏幕上
说明:
(1) put函数的参数不但可以是字符,还可以是字符的ASCII代码(也可以是一个整型表达式)。
例如以下语句都可以将字符A显示在屏幕上:
cout.put(65);
或
cout.put(20+45);
(2) 可以在一个语句中连续调用put函数。
例如:
cout.put(65).put(66),cout.put('\n');
2.get函数
常用的调用形式为:
cin.get(字符型变量)
功能: 是从输入流中读取一个字符(包括空白符),赋给字符变量,如果读取成功则函数返回非0值,如失败(遇文件结束符EOF)则函数返回0值。
#include <iostream> //get函数应用举例。
using namespace std;
int main()
{
char ch;
cout<<"Input:";
while(cin.get(ch))
cout.put(ch);
return 0;
}
运行时,如果输入:
123 abc xyz
则输出:
123 abc xyz
当输入“Ctrl+z”及回车时,程序读入的值是EOF,程序结束。
ch=cin.get();这样的用法并不可取,,,因为cin.get()的返回值类型是int.其中可能包含其他信息...虽说赋值操作截取的数值是正确的...(兼容C?)
3.getline函数
getline函数常用的的调用形式为:
cin.getline(字符数组,字符个数n,终止标志字符)
或 //注意:只读取 n-1个字符 ,因为要有一个字符串终止符'\0'
cin.getline(字符指针,字符个数n,终止标志字符)
功能: 从输入流读取n-1个字符,赋给指定的字符数组(或字符指针指向的数组),然后插入一个字符串结束标志‘\0’。
如果在读取n-1个字符之前遇到指定的终止字符,则提前结束读取,然后插入一个字符串结束标志'\0'。
例子 用getline函数读入一行字符。
#include<iostream>
using namespace std;
int main()
{
char line[20];
cout<<"输入一行字符:"<<endl;
cin.getline(line,20,'t'); //读入19个字符或遇字符't'结束
cout<<line;
return 0;
}
本程序连续读入一串字符,最多读取19个字符赋给字符数组line,或遇到字符't'提前停止。
说明:
请注意用“cin>>”和成员函数“cin.getline()”读取数据的区别。
(1) 使用“cin>>”可以读取C++标准类型的各类数据(如果经过重载,还可以用于输入自定义类型的数据),而用“cin.getline()”只能用于输入字符型数据。
(2) 使用"cin>>" 会直接忽略前面的空白字符(包括空格、tab键、回车键),然后再遇上空白符或者回车而终止(并不从缓冲区中去除终止符)
(3) 使用cin.getline() 会直接把空白字符当普通字符对待,直到遇上回车(或者指定的终止符(并从流中去除该字符)),或者字符数量达到上限.
(4) 使用cin.get(超过两个参数时重载) 仿制 cin.getline() 唯一区别就是 流中会保留终止字符
4.ignore函数
ignore函数常用的的调用形式为:
cin.ignore(n, 终止字符)
功能:是跳过输入流中n个字符(默认个数为1),或在遇到指定的终止字符(默认终止字符是EOF)时提前结束。
例如:
cin.ignore(10,'t')
跳过流入流中10个字符,或遇字符't'后就不再跳了('t'字符仍然保留在流中)
说明:
ignore函数可以不带参数或只带一个参数,
只跳过1个字符(n的默认值为1,默认终止字符是EOF)
例如:
cin.ignore()
相当于
cin.ignore(1,EOF )
cin.clear(); flush the flags
cin.sync(); clear the buffer
rewind(stdin); ???
C++ 容易忽略的输入输出特性
1 cin cout cin.get() cin.get(ch)的返回值
(1)cin ,cout 就不用多说了还是返回一个iostream对象,因此它们可以这么使用。
cin >> var1 >> var2 >>var3;
cout << var1 << var2 <<var3<<endl;
cin.get() 没有参数时,返回值是一个整数,所以通常这么用
while((ch=cin.get()) != EOF)
{
cout << ch;
}
cin.get(ch)代参数时,返回的也是一个iostream对象,因此可以这么用
cin.get(a).get(b).get(c);
2 cin.get(buffer, num, terminate) cin.getline(buffer, num, terminate)的区别
注:terminate 一般为 '\n'
二者都是每次读取一行字符,或是碰到ternimate指定的字符终止或是读的字符数超过num - 1终止。
区别是cin.get会把terminate留在缓冲区中,因此下次读到的第一个字符就是terminate字符,相反,cin.getline()则会丢弃缓冲区中的terminate字符。
#include <iostream>
using namespace std;
int main()
{
char stringOne[255];
char stringTwo[255];
cout << “Enter string one:”;
cin.get(stringOne,255);
cout << “String one: “ << stringOne << endl;
cout << “Enter string two: “;
cin.getline(stringTwo,255);
cout << “String two: “ << stringTwo << endl;
cout << “\n\nNow try again...\n”;
cout << “Enter string one: “;
cin.get(stringOne,255);
cout << “String one: “ << stringOne<< endl;
cin.ignore(255,’\n’);
cout << “Enter string two: “;
cin.getline(stringTwo,255);
cout << “String Two: “ << stringTwo<< endl;
return 0;
}
看输入输出结果:
Enter string one:once upon a time
String one: once upon a time
Enter string two: String two:
Now try again...
Enter string one: once upon a time
String one: once upon a time
Enter string two: there was a
String Two: there was a
3 两个比较有用的函数:peek(), putback() 和 ignore()
cin.peek(ch); 忽略字符ch
cin.putback(ch); 把当前读到的字符替换为ch
cin.ignore(num, ch); 从当前字符开始忽略num个字符,或是碰到ch字符开始,并且把ch字符丢丢掉。
#include <iostream>
using namespace std;
int main()
{
char ch;
cout << “enter a phrase: “;
while ( cin.get(ch) != 0 )
{
if (ch == ‘!’)
cin.putback(‘$’);
else
cout << ch;
while (cin.peek() == ‘#’)
cin.ignore(1,’#’);
}
return 0;
}
输入输出结果:
enter a phrase: Now!is#the!time#for!fun#!
Now$isthe$timefor$fun$
4 cout.put() cout.write()
与输入相同,cout.put(ch) 返回一个iosream对象,因此可以连续使用
cout.write(text,num) 输出text中的num个字符,如果num > strlen(text), 则后面输出的是text之后的内存中的随机的字符。
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char One[] = “One if by land”;
int fullLength = strlen(One);
int tooShort = fullLength -4;
int tooLong = fullLength + 6;
cout.write(One,fullLength) << endl;
cout.write(One,tooShort) << endl;
cout.write(One,tooLong) << endl;
return 0;
}
输入结果:
One if by land
One if by
One if by land i?!
1 超出数据类型指定长度的赋值
(1)无符号数据类型
unsigned char ch1= 336;
unsigned char ch2 = -1;
上面两个赋值都超出了unsigned char 类型的范围,大部分的编译器对这种情况是这么处理的:允许赋值,仅仅给出一个警告,但是是经过modulo之后的值。
cout<<ch1<<ch2<<endl; 而这的结果是 ch1 = 336 modulo 256 = 80, ch2 = -1 modulo 256 = 255 。 取余数。
(2) 对于有符号的书来说,要根据具体的编译器来定。
2 浮点型的有效数字
float类型仅提供6位有效数字,double类型至少提供10位有效数字
3 definitions 和declarations(变量的定义和声明)
主要的区别就是定义要分配存储空间,声明不分配存数空间,仅仅谁说明名字是什么,类型是什么而已。看看下面集中定义和声明的方式:
extern int i; // 声明
int i; //定义
extern double pi = 3.14 // 定义
4 变量的作用范围
从声明开始到范围结束,局部变量覆盖全局变量,看下面的代码片段
int i = 100, sum = 0;
for (int i = 0; i != 10; ++i)
sum += i;
std::cout << i << " " << sum << std::endl
输出结果应该是: i= 100 sum = 45
int sum = 0;
for (int i = 0; i != 10; ++i)
sum += i;
std::cout << "Sum from 0 to " << i << " is " << sum << std::endl;
编译出错,因为i没有被定义(cout中的i)
5 const 变量的作用范围
const的变量的作用范围是本文件,即使它被声明成全局变量。要想在其他文件中使用本文件中定义的const变量,看下面代码
// file_1.cc
// defines and initializes a const that is accessible to other files
extern const int bufSize = fcn();
// file_2.cc
extern const int bufSize;
// uses bufSize from file_1
//uses bufSize defined in file_1
for (int index = 0; index != bufSize; ++index)
// ...
在声明和定义处都需要加extern关键字
6 vector<string>::const_iterator 和 const vector<string>::iterator
看下面两个例子,就能明白二者的区别
for (vector<string>::const_iterator iter = text.begin();
iter != text.end(); ++ iter)
*iter = " "; // error: *iter is const
vector<string>::const_iterator iter 允许自身变化,但不允许修改它下面指向的数据,即指向的内容是常量
vector<int> nums(10); // nums is non const
const vector<int>::iterator cit = nums.begin();
*cit = 1; // ok:cit can change its underlying element
++cit; // error: can't change the value of cit
const vector<int>::iterator cit 允许修改它指向的下面的数据,不允许自身的变化,即本身是个常量
7 typedef string *pstring
const pstring cstr; 解释这个声明的意思?
相信大部分人是这么理解的,typedef string *pstring 是定义了一个指向string 的指针类型,因此const pstring cstr <=> const string * cstr
即 指向一个const string的指针,但是这是错误的。
正确的解释应该是, cstr是一个const指针,指向string类型的字符串