2 get( )
面向行的输入函数。
位于istream中,有十几个变体,其中一个与getline( )函数类似,接受的参数相同,参数解释也一样。
但get函数并不再读取和丢弃换行符,而是将其留在输入队列中。
cin.get(name,ArSize );
cin.get(gender,ArSize ); //会产生问题
这是由于第一次输入后,换行留在队列中,因此第二次调用时,看到的就是换行符,所以误以为到了行尾
解决的办法是使用get函数的另外一种变体,无参数的get( ),它的功能是读取包括换行符在内的下一个字符所以可以:
cin.get(name,ArSize );
cin.get();
cin.get(gender,ArSize );
或者使用拼接的方式
cin.get(name,ArSize ).get();
cin.get(gender,ArSize ); //会产生问题
之所以可以这样做是因为,cin.get(name,ArSize)返回的是一个cin对象,该对象随后被用来调用get()
同理可以cin.getline(name1,ArSize).getline(name2,ArSize);
之所以使用get()的原因是老实的c没有getline(),并且get()使输入更加详细,使得检查错误也更加容易
3 空行和其他问题
空行问题:当前的做法是,当get() 读取空行后将设置失效位(fallbit),接下来的输入将会被阻断,但可以用cin.clear()来恢复输入
字符串超长:getline() & get()将会把余下的字符留在输入队列中,而且gerline函数还会设置失效位来阻止之后的输入
#include
#include
void
lq_strcpy_strcat_demo()
{
using
namespace
std;
cout
<<
"-----------不使用string类对于字符串的操作-----------\n"
;
char
dst[30] = {
"Doo..."
};
char
src[30]=
"Hello, how are you."
;
cout
<<
"初始src="
<<
src
<<
endl;
cout
<<
"初始dst="
<<
dst
<<
endl;
strcpy_s(dst, src);
//将字符串src复制到字符数组dst中
strcat_s(dst,
",sorry..."
);
//将字符串src附加到到字符数组dst尾部
// 'strcpy': This function or variable may be unsafe.
//Consider using strcpy_s instead.
//To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
cout
<<
"现在src="
<<
src
<<
endl;
cout
<<
"现在dst="
<<
dst
<<
endl;
cout
<<
"-----------使用string类对于字符串的操作-----------\n"
;
string
s1 =
"To tell you, "
;
string
s2 =
"I am sorry for breaking your heart!"
;
string
s3;
s2
=
s1
+
s2;
s3
=
s2;
cout
<<
"s1="
<<
s1
<<
endl;
cout
<<
"s2="
<<
s2
<<
endl;
cout
<<
"s3="
<<
s3
<<
endl;
cout
<<
"s2=s1+s2="
<<
s2
<<
endl;
cout
<<
"s3="
<<
s3
<<
endl;
}
结构
结构的赋值
例子:
struct inflatable
{
char name[20];
float volue;
double price;
};
inflatable bouquet={"sun", 0.20, 12.40};
结构体的位字段
C/C++都允许指定占用特定位数的结构体成员,目的是方便创建与某个硬件设备上的寄存器对应的数据结构。
字段的类型为整形或者枚举,接下来是冒号,冒号后面是一个数字,它指定了使用的位数。可以提供没有指定的字段来提供间距。每个成员都被称为位字段(bit field )
位字段一般用于低级编程中.一般来说可以使用整型和安慰运算的方式来代替这种方式.
struct MyRegister
{
unsigned int SN : 4;
unsigned int : 4;
bool RW : 1;
bool cs : 1;
};
MyRegister r1 = { 10,true ,false };
if (r1.cs) { ... };
if (r1.RW == 0) { ... };
共用体
union是一种数据格式,它能够存储不同的数据类型,但
只能同时存储其中的一种类型
union
one4all
//one for all
{
int
int_val;
double
double_val;
long
long_val;
};
one4all
p;
if
(case1)
{
p.int_val = 20;
}
if
(case2)
{
p.double_val = 3.1245;
}
if
(case3)
{
p.long_val = 655637;
}
共用体的用途之一是,当数据项使用多种格式(但不会同时使用)时可以节省空间
枚举
enum color { red,orange, yellow,green ,blue };
- color 是一个枚举,是新类型的名称.可以用枚举名来声明这种类型的变量 color mycolor;//mycolor是color类型的一个变量
- red,orange, yellow,green ,blue 等作与符号变量,对应于整数值的0~4.这些常量叫做枚举量(enumerator)
默认情况下是将整数值赋给枚举量,第一个枚举量的值是0,第二个为1,依此类推.可以通过显式的指定整数值来覆盖默认值
在没有进行强制类型转换的前提下,只能将定义枚举时的使用的枚举量赋给这个枚举的变量.例子中,color变量受到限制,可能的值只有5个.如果将非法的值赋给它,例如,mycolor=20;有的编译器将会报另一些将会发出警告.
对于枚举只定义了赋值运算符,而没有定义算数运算符
mycolor=red;//合法
mycolor++;//非法
mycolor=red+blue;//非法!
...
枚举量是整型,可能被提升为int型,但是,int型不能自动转换为枚举型
int clr=blue;//合法,枚举型提升为int型
mycolor=3;//非法 ,int型不能自动转换为枚举型
clr=red+4;//合法,枚举型转换为int型
...
如果int型是有效的可以通过强制类型转换将它赋值给枚举变量
mycolor=color(3);
如果试图将一个不适当的值通过强制类型转换赋给枚举变量,结果将是不确定的
枚举更常用来定义相关的符号常量,而不是新的类型.例如可以使用枚举来定义switch中常用的符号常量,如果只是使用常量,而不是用枚举类型的变量,则可以省略枚举类型的名称
例如:
enum { red,orange, yellow,green ,blue };
可以使用赋值运算符来显式地设置枚举量的值
例如:
enum bits{ one=1,two=2,four=4;ten=10 };
指定的值必须是整数,可以显式地定义其中一些枚举量的值:
例如:enum
step
{
first
,
second
= 249,
third
};
first默认为0,后面没有初始化的值比前面的大1,因此例子中的third值为250
此外,还可以创建多个值相同的枚举量
例如:enum
{
null
,
zero
=0,
first
,
one
= 1 };
新的C++版本可以将long, long long型赋值给枚举型
对于枚举的取值范围:'
取值范围的定义如下:
上限:先找到枚举量的最大值,然后找出2的幂中,比这个最大值大的且离的最近的值,将这个值减一,就得到了枚举值的上限.
举个栗子,上面的step,third是250<256(2的8次幂),所以step的取值上限就是256-1=255
下限:首先,找出枚举值的最小值,如果是大于等于零,则取值范围下限是0
若<0则,采用与找上限相类似的方式,先不看符号,只不过将最后的值加上负号之后,再加上1.例如,如果最小的枚举值是-7,7<8,所以最小值就是-9+1=-7
原先的C++,只有声明中的那些值才有效。现在,通过强制类型转化,增加了可以赋值的范围。
例如,上面的step,取值范围是0~255,之间的所有值都可以取到。
step flag=step(211);//合法,211在0~255之间