文章目录
- 字符与数字
char
和int
类型能自动互相转换, 注意++ch
得到char
类型的值, 而ch + i
会得到int
类型的值- 如果在输入时试图将
char
类型的值给int
变量, 则会使输入失效, 无法再读取输入, 一般还会将此int
变量设置为0。
因此, 在使用switch
语句时, 最好用char
类型的变量作为标签
- sizeof运算符, size()函数指出数组的长度, 而strlen()函数则指出存储在数组中的字符串的长度(不包括\0)。
- 字符串输入(注意读取非字符串时不会处理输入的回车符)
cin>>charr
: 使用空白, 如空格、制表符和换行符确定字符串的结束位置- cin.getline(): 使用换行符确定行尾, 读取时用空字符\0替换\n
cin.getline(charr, size)
: 将一行中的最多size-1个字符读入charr中
cin.get()
:cin.get(charr1, size1).cin.get().cin.get(charr2, size2)
cin.get()
: 读取并返回下一个字符cin.get(ch)
: 读取下一个字符, 通过引用存入ch中cin.get(charr, size)
: 将一行中的最多size-1个字符读入charr中
- 空行和其他问题
- get()读取空行后会设置failbit, 阻断接下来的输入, 可用cin.clear()回复输入
- 如果输入行中的字符数比指定的多, 则cin.get()、getline()会将余下的字符留在出入队列中, getline()还会设置failbit
- cstring(以前为string.h)
- strcpy(), strncpy() (第一个参数为目标地址)
- strcat(), strncat()
- strlen()
- 其他形式的字符串字面值
- wchar_t: L""
- char16_t(C++11): u""
- char32_t(C++11): U""
- UTF-8: u8""
- raw字符串: R""
- 使用"(和)"作为定界符
- 在"和(或)之间加入任意个基本字符可以自定义定界符, 用来替代"(和)", 不过两处要相同
- 结构中的位域(bit field, 也称位字段)
- 类型: unsigned int, (bool), 枚举(enum)
- 语法:
<type> <identifier>: <bits>;
1.1 字符函数库 cctype
函数名称 | 功能 |
---|---|
isalnum() | 检查字符是否是字母或数字 |
isalpha() | 检查字符是否是字母 |
isbkank() | 检查字符是否是空格 |
iscntrl() | 检查字符是否是控制字符 |
isdigit() | 检查字符是否是十进制数字 |
isgraph() | 检查字符是否是能以图形表示的字符 |
islower() | 检查字符是否是小写字母 |
isprint() | 检查字符是否是可打印的(isgraph() 检查为真的字符加上空格) |
ispunct() | 检查字符是否是标点符号 |
isspace() | 检查字符是否是标准空白字符, 如空格、进纸、换行符、制表符等 |
isupper() | 检查字符是否是大写字母 |
isxdigit() | 检查字符是否是十六进制数字 |
tolower() | 将大写字符转换为小写形式 |
toupper() | 将小写字符转换为大写形式 |
ASCII values | characters | iscntrl | isblank | isspace | isupper | islower | isalpha | isdigit | isxdigit | isalnum | ispunct | isgraph | isprint |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x00 … 0x08 | NULL, (other control codes) | o | |||||||||||
0x09 | tab (’\t’) | o | o | o | |||||||||
0x0A … 0x0D | (white-space control codes: ‘\f’,’\v’,’\n’,’\r’) | o | o | ||||||||||
0x0E … 0x1F | (other control codes) | o | |||||||||||
0x20 | space (’ ') | o | o | o | |||||||||
0x21 … 0x2F | !"#$%&’()*+,-./ | o | o | o | |||||||||
0x30 … 0x39 | 0123456789 | o | o | o | o | o | |||||||
0x3a … 0x40 | :;<=>?@ | o | o | o | |||||||||
0x41 … 0x46 | ABCDEF | o | o | o | o | o | o | ||||||
0x47 … 0x5A | GHIJKLMNOPQRSTUVWXYZ | o | o | o | o | o | |||||||
0x5B … 0x60 | [\]^_` | o | o | o | |||||||||
0x61 … 0x66 | abcdef | o | o | o | o | o | o | ||||||
0x67 … 0x7A | ghijklmnopqrstuvwxyz | o | o | o | o | o | |||||||
0x7B … 0x7E | {|}~ | o | o | o | |||||||||
0x7F | (DEL) | o |
1.2 指针、数组与字符串
- 指针初始化时如果没有使用, 应该赋值为NULL, 避免修改未知的内存
- 数组名在大部分时候被解释为数组中第一个元素的地址,只有在使用sizeof运算符的时候除外
- 指针算数以指针所指类型的长度为一个单位长度
- C-style string的实际值为其第一个字符在内存中的地址, 注意: C++并不保证字符串字面值被唯一地存储
- 将char*类型指针作为参数时,cout会从该字符开始打印, 直到遇到空字符为止, 对其他类型的指针, cout会直接打印指针的值
- 所有初始化赋值语句都是将变量名, 左边的其他成分是对变量名的修饰
int* arr[10];
将声明一个包含十个int*
类型指针的数组
int (*arr)[10];
将声明一个指向一个包含十个int
值的数组的指针- 当且仅当在函数头或函数声明中时,
int arr[]
与int* arr
等效, 且int arr[]
只能在这种情况下使用(除非是在初始化时且指定了确定的值, 这时会自动确定数组大小)
1.3 文件尾条件
- 检测到EOF后
cin
将eofbit
和failbit
都设置为1,cin.eof()
返回true
,cin.failbit()
返回ture
- 注意, 检验文件尾并不是预先报告, 而是在读取后报告
- 设置
eofbit
为true
后, cin将关闭对输入的进一步读取, 这会导致用cin.get()
锁住屏幕的技术在这里不适用 cin.clear()
函数可以清除eofbit
从而恢复输入iostream
类提供了一个可以将istream
如cin
转换为bool
类型的隐式转换函数
因此可以用一种更简洁且通用 (可以检查其他错误) 的方法
char ch;
while(cin.get(ch)){
// do something here
}
1.4 cin.get() 与 cin.put()
在cstdio
中定义了getchar()
与putchar()
, 可以用cin.get()
与cin.put()
实现相同的功能。
相应地用EOF检验文件尾。
下面代码中还使用int
变量代替char
变量。
char ch; // int ch;
cin.get(ch);
while(cin.fail() == flase) // ch != EOF
{
cout << ch; // cin.put(ch);
++count;
cin.get(ch); // ch = cin.get();
}
int ch; // char ch;
cin.get(ch);
while(ch != EOF) // cin.fail() == flase
{
cin.put(ch); // cout << ch;
++count;
ch = cin.get(); // cin.get(ch);
}
1.5 实践使用
1.5.3 混合输入数字、字符和字符串
使用>>
运算符从输入流获取数字或字符时会将\n
留在输入流。\n
会被留在输入流中
1.5.2 菜单雏形 (持续输入字符)
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
cout << "Please enter one of the following choices: " << endl;
cout << "c) carnivore\tp) pianist" << endl;
cout << "h) show help\tq) quit" << endl;
char ch;
if(!(cin >> ch)) exit(EXIT_FAILURE);
while(ch != 'q'){
switch(ch)
{
case 'c':
cout << "Tigger, dog, bear or wolf?" << endl;
break;
case 'p':
cout << "No, I'm not a pianist." << endl;
break;
case 'h':
cout << "Please enter one of the following choices: " << endl;
cout << "c) carnivore\tp) pianist" << endl;
cout << "h) show help\tq) quit" << endl;
break;
default:
cout << "Enter \'h\' for help." <<endl;
break;
}
if(!(cin >> ch)) exit(EXIT_FAILURE);
}
return 0;
}
1.5.3 类型不匹配
- 若用
cin
向int
类型变量n
输入字符串n
的值不变- 不匹配的输出将被留在输出队列中
cin
对象中的一个错误标记被设置
- 处理对策
- 重置
cin
以接受新的输入 - 删除错误输入
- 提示用户再输入
- 重置
#include <iostream>
const int MAX = 5;
int main()
{
using namespace std;
//getdata
int golf[MAX];
cout << "Please enter your golf scores.\n";
cout << "You must enter " << MAX << " turns.\n";
int count;
for (count = 0; count < MAX; count++) {
cout << "Round #" << count + 1 << ": ";
while (!(cin >> golf[count])) {
cin.clear(); // reset input
while (cin.get() != '\n')
continue; // get rid of bad input
cout << "Please enter a number: ";
}
}
// calculate average
double total = 0.0;
for (count = 0; count < MAX; count++)
total += golf[count];
// report results
cout << "Average score = " << total / MAX;
return 0;
}
Please enter your golf scores.
You must enter 5 turns.
Round #1: 88
Round #2: 87
Round #3: Must I?
Please enter a number: 103
Round #4: 94
Round #5: 86
Average score = 91.6
1.7 枚举 enum
语法:
enum <enumeration> {<enumeraters>};
枚举量的值
- 底层实现为整数类型, 具体依赖于实现
- 第一个枚举量默认为0, 每一个未直接设置的枚举量的值比前一个大1
- 可以创建多个值相同的枚举量
- 取值范围: 容纳所有枚举量所需的最小的内存所能表示的数
枚举变量的限制
- 枚举类型没有定义算数运算符, 但可以作为整数进行运算, 因为在表达式中枚举量会转换为整数
- 枚举量会被提升为整数类型, 但非枚举量不能隐式地转换为枚举量
- 可以显式地将整数转换为枚举量。对非有效整数, 结果是不确定的, 不会出错, 但得不到可依赖的结果
enum clothes {hat, trousers, shirt, pants};
clothes mine = shirt;
clothes yours = 0; //error
1.7.1 作用域内枚举(C++11)
enum class <enumeration> {<enumeraters>};
enum struct <enumeration> {<enumeraters>};
这样定义的枚举,要使用枚举量的话要用作用域解析运算符来限定。可以避免不同枚举的枚举量之间发生冲突。
另外,普通枚举量在需要的时候能自动转换为整型,但作用域内枚举不行。
enum class egg{small, medium, big, large};
enum class t_shirt{small, medium, large, xlarge};
egg mine = egg::large;
t_shirt yours = t_shirt::large;
1.7.2 指定枚举量底层类型
在C++11中还可以指定枚举量的底层整数类型。C++11中枚举量的底层整数类型为int
,但可以通过以下语法指定所需类型。
enum class : short egg{small, medium, big, large};
enum : short t_shirt{small, medium, large, xlarge};