命令行参数(仿C)
代码:
#include<stdio.h>
int main(int argc, char* argv[])
{
printf("%d arguments in all.\n", argc);
for(int i = 0; i < argc; i++)
printf("%d: %s\n", i+1, argv[i]);
return 0;
}
命令行输入:
...>g++ option.cpp -o option.exe
...>option -i infile -o outfile
命令行输出:
5 arguments in all.
1: option
2: -i
3: infile
4: -o
5: outfile
其中第一个参数为程序的路径
输入输出,基本类型
- C++中会自动拼接空白隔开/连续的字符串
- 字符与数字
char
和int
类型能自动互相转换, 注意++ch
得到char
类型的值, 而ch + i
会得到int
类型的值- 如果在输入时试图将
char
类型的值给int
变量, 则会使输入失效, 无法再读取输入, 一般还会将此int
变量设置为0。
因此, 在使用switch
语句时, 最好用char
类型的变量作为标签
- sizeof运算符, size()函数指出数组的长度, 而strlen()函数则指出存储在数组中的字符串的长度(不包括\0)。
- 字符串输入(注意读取非字符串时不会处理输入的回车符)
cin>>charr
: 使用空白, 如空格、制表符和换行符确定字符串的结束位置cin.getline()
: 使用换行符确定行尾, 读取时用空字符\0替换\ncin.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""
- raw字符串
- 使用"(和)"作为定界符
- 在"和(或)之间加入任意个基本字符可以自定义定界符, 用来替代"(和)", 不过两处要相同
- 结构中的位域(bit field, 也称位字段)
- 类型: unsigned int, (bool), 枚举(enum)
- 语法:
<type> <identifier>: <bits>;
- 枚举enum
- 语法:
enum <enumeration> {<enumeraters>};
- 枚举量的值
- 底层实现为整数类型, 具体依赖于实现
- 第一个枚举量默认为0, 每一个未直接设置的枚举量的值比前一个大1
- 可以创建多个值相同的枚举量
- 取值范围: 容纳所有枚举量所需的最小的内存所能表示的数
- 在严格的限制中
- 枚举类型没有定义算数运算符, 但可以作为整数进行运算, 因为在表达式中枚举量会转换为整数
- 枚举量会被提升为整数类型, 但非枚举量不能隐式地转换为枚举量
- 可以显式地将整数转换为枚举量。对非有效整数, 结果是不确定的, 不会出错, 但得不到可依赖的结果
- 语法:
enum clothes {hat, trousers, shirt, pants};
clothes mine = shirt;
clothes yours = 0; //error
- 类型不匹配
- 若用
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
字符函数库ctype
函数名称 | 功能 |
---|---|
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 | NUL, (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 |
文件尾条件
- 检测到EOF后
cin
将eofbit
和failbit
都设置为1,cin.eof()
返回true
,cin.failbit()
返回ture
- 注意, 检验文件尾并不是预先报告, 而是在读取后报告
- 设置
eofbit
为true
后, cin将关闭对输入的进一步读取, 这会导致用cin.get()
锁住屏幕的技术在这里不适用 cin.clear()
函数可以清除eofbit
从而恢复输入iostream
类提供了一个可以将istream
如cin
转换为bool
类型的隐式转换函数
因此可以用一种更简洁且通用 (可以检查其他错误) 的方法
c++ char ch; while(cin.get(ch)){ // do something here }
指针、数组与字符串
- 指针初始化时如果没有使用, 应该赋值为NULL, 避免修改未知的内存
- 数组名在大部分时候被解释为数组中第一个元素的地址,只有在使用sizeof运算符的时候除外
- 指针算数以指针所指类型的长度为一个单位长度
- C-style string的实际值为其第一个字符在内存中的地址, 注意: C++并不保证字符串字面值被唯一地存储
- 将char*类型指针作为参数时,cout会从该字符开始打印, 直到遇到空字符为止, 对其他类型的指针, cout会直接打印指针的值
- 所有初始化赋值语句都是将变量名, 左边的其他成分是对变量名的修饰
int* arr[10];
将声明一个包含十个int*
类型指针的数组
int (*arr)[10];
将声明一个指向一个包含十个int
值的数组的指针
后者与int arr[][10];
等效
C++小细节
- 基于范围的for循环
c++ double prices[5] = {4.99, 10.99, 6.87, 9.58, 11.49}; for(double x : prices) cout<<x<<endl;
- 逻辑运算符会短路, 如
&&
左侧的表达式若判断为false
, 则不会判断/执行右侧的表达式
const指针和指向const的指针
*
直接接触指针名的就是指向const的指针
int i = 10;
int j = 10;
// 变量值不可修改
const int ci = i;
ci = 1; //error
// 1. 指针指向的内存不可修改
const int* pi1 = &i;
*pi1 = 1; // error
pi1 = &j;
// 2. 等价于 1
int const* pi2 = &i;
*pi2 = 1; // error
pi2 = &j;
// 3. 指针不可修改
int* const pi3 = &i;
*pi3 = 1;
pi3 = &j; // error
// 4. 没有这种语法
const* int pi4 = &i; // error
// const int*类型的值不能用于初始化int*变量
int* pi4 = pi1; // error