C++入门笔记--复杂的数据类型--数组和getline()函数

学习完复杂的数据类型的设计思路和使用习惯,就开始面向对象的学习。

1.数组

数组是许多程序设计语言的重要组成部分,尤其是在C语言程序里会经常碰到他们。

数组的优点在于,一个数组可以把多个同类型的值存储在同一变量名下,需要被声明为一种特定的类型。type name[length].

下面用C++实现一个试用数组的任务,并谈谈在使用中有哪些地方需要注意。

编程任务:定义一个数组容纳十个整数,这些整数来自用户的输入,我们将这些值的累加和,平均值计算并输出

#include<iostream>

using namespace std;

int main(){
	int array[10];
	float total=0;
	cout<<"请输入10个整形数据:\n\n";
	
	for(int i=0;i<10;i++){
		cout<<"请输入第"<<i+1<<"个数据:";
		cin>>array[i];
		
		total += array[i];
	}
	cout<<"累加和是:"<<total;
	cout<<"\n平均值是:"<<total/10;
	return 0;
} 

可是很显然,这个程序很不成熟,通用性也不强,所以就要对他做进一步的改进。

下面改进的代码

  1. 对数组的长度做了宏定义,或者也可以用静态变量(const unsigned short ITEM=5)。
  2. 再者就是对输入的数据做了一个检查,如果输入的数据不合法的话,就要进行异常处理。前面几个笔记里已经讲过cin>>array[i]如果调用成功的话返回值是1,否则是0.所以要充分利用这个特点,当其调用不成功的时候就要对它做异常处理---while语句块里的内容,但是在这里十分必要的一个语句是cin.clear(),这个函数可不是用来清除缓冲区的。
  3. cin.clear()默认参数为0,即无错误,正常操作.我们可以继续输入,用cin来读取。但是当我们输入英文字母'k'时,不是int型,它的状态标识改为fail,即错误,这时候cin就不能再正常读取了,我们也无法输入了。在这里用cout对用户输出信息,再用cin.clear让错误标识改回为0,让我们可以继续输入,再清空流数据继续输入(ignore).如果我们没有了cin.clear,则会进入死循环,其过程为我们输入了英文字母,它的状态标识便为fail,当运行到条件判断时,便总是回到错误的条件表示里,并且我们再也没办法输入,因为错误的表示关闭了cin,所以会进入死循环.
#include<iostream>
#define ITEM 5

using namespace std;

int main(){
//	const unsigned short ITEM=5; 这句和开头的宏定义起的作用差不多一样 根据自己的喜好二选一
	
	int array[ITEM];
	float total=0;
	cout<<"请输入"<<ITEM<<"个整形数据:\n\n";
	
	for(int i=0;i<ITEM;i++){
		cout<<"请输入第"<<i+1<<"个数据:";
		
		while(!(cin>>array[i])){//对输入数据做检查
			
			cout<<"请重新输入一个合法的值!\n";
			cin.clear();//将错误的标识符重新改为0 否则就会陷入死循环 
			cin.ignore(100,'\n');//清除缓冲区的内容 
		};
		
		
		total += array[i];
	}
	cout<<"累加和是:"<<total;
	cout<<"\n平均值是:"<<total/ITEM;
	return 0;
} 

 在C语言里,字符被实际存储在一个字符数组里。在C++里我们可以用同样的方式来实现字符串的存储,但是我们一把不用,因为它提供了一个更好的std::string类型。

编程任务:分别尝试用C和C++实现将用户输入的字符串打印出来

//C语言

#include<stdio.h>

int main(){
	const unsigned short LENGTH = 100;
	char str[LENGTH];
	gets(str);
	puts(str);
}

下面用C++来实现,比较两次输入发现第一次输出只有I,第二次全部输出,说明cin>>str接收到空格的时候就以为要停止了。所以用getline()来获取一段字符串  。

//C++错误示范
#include<iostream>
#include<string>
int main(){
	std::string str;
	std::cout<<"请任意输入一段字符串:\n";
	std::cin>>str;
	std::cout<<str;
	
	return 0;
} 

//输入:I love C++!
//输出:I
//输入:IloveC++
//输出:IloveC++

 getline():

getline()的原型是istream& getline ( istream &is , string &str , char delim );其中 istream &is 表示一个输入流,譬如cin;string&str表示把从输入流读入的字符串存放在这个字符串中(可以自己随便命名,str什么的都可以);char delim表示遇到这个字符停止读入,在不设置的情况下系统默认该字符为'\n',也就是回车换行符(遇到回车停止读入)。

//C++正确示范
#include<iostream>
#include<string>
int main(){
	std::string str;
	std::cout<<"请任意输入一段字符串:\n";
	std::getline(std::cin,str);
	
	std::cout<<str<<"\n";
	
	return 0;
} 

//输入:I love C++!
//输出:I love C++!

关于getline()函数的进一步解释:

//getline()函数,在C++premer中,标准string类型第二小节就是“用getline读取整行文本”。书上给的程//序如下:

int main()
{
    string line:
    while(getline(cin,line))
    cout<<line<<endl;
    return 0;
}

/*
大家会发现运行时怎么也跳不出循环,甚至会发生各种莫名其妙的错误。这是为什么呢?在这里我给大家做一个详细的讲解。

首先给大家介绍一下getline()函数(个人觉得百度百科给的果断不够详细)

大家百度会发现getline()的原型是istream& getline ( istream &is , string &str , char delim );

其中 istream &is 表示一个输入流,譬如cin;string&str表示把从输入流读入的字符串存放在这个字符串中(可以自己随便命名,str什么的都可以);char delim表示遇到这个字符停止读入,在不设置的情况下系统默认该字符为'\n',也就是回车换行符(遇到回车停止读入)。给大家举个例子:
*/

string line;
cout<<"please cin a line:"
getline(cin,line,'#');
cout<<endl<<"The line you give is:"line;

/*
那么当我输入"You are the #best!" 的时候,输入流实际上只读入了"You are the ",#后面的并没有存放到line中(应该是在缓冲区里吧)。然后程序运行结果应该是这样的:
*/

please cin a line:You are the #best!
The line you give is:You are the 
/*

而且这里把终止符设为#,你输入的时候就算输入几个回车换行也没关系,输入流照样会读入,譬如*/
please cin a line:You are the best!
//这里输入了一个回车换行
Thank you!
# //终止读入

The line you give is:You are the best!
//换行照样读入并且输出
Thank you!

/*
以上就是getline()函数一个小小的实例了。

那么如果把getline()作为while的判断语句会怎么样呢?

让我们一起来分析一下while(getline(cin,line))语句

注意这里默认回车符停止读入,按Ctrl+Z或键入EOF回车即可退出循环。

在这个语句中,首先getline从标准输入设备上读入字符,然后返回给输入流cin,注意了,是cin,所以while判断语句的真实判断对象是cin,也就是判断当前是否存在有效的输入流。在这种情况下,我想只要你的电脑不中毒不发神经你的输入流怎么会没有效?所以这种情况下不管你怎么输入都跳不出循环,因为你的输入流有效,跳不出循环。

然而有些同学误以为while判断语句的判断对象是line(也就是line是否为空),然后想通过直接回车(即输入一个空的line)跳出循环,却发现怎么也跳不出循环。这是因为你的回车只会终止getline()函数的读入操作。getline()函数终止后又进行while()判断(即判断输入流是否有效,你的输入流当然有效,满足条件),所以又运行getline()函数,所以,就这样....
*/

C++里关于string类的内建功能非常多,例如

  1. 提取子字符串:

    string常用截取字符串方法有很多,但是配合使用以下两种,基本都能满足要求:

    find(string strSub, npos);

    find_last_of(string strSub, npos);

    其中strSub是需要寻找的子字符串,npos为查找起始位置。找到返回子字符串首次出现的位置,否则返回-1。

  2. strmap(str1,str2):比较字符串1和字符串2是否想等。返回一个整数。(1)如果返回0则说明字符串1和字符串2相等(2)如果返回的数为正整数,则说明字符串1大于字符串2(3)如果返回的数为负整数,则说明字符串1小于字符串2

  3. strcat(str1,str2);

    将两个字符串连接起来。如a[3]={'a','b'};b[3]={'c','d'};cout<<strcat(a,b)<<endl;

     

     

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值