C++ 容易忽略的特性

(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类型的字符串

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值