交互
大约 7 分钟
交互
C++语句类型
- 声明语句
- 赋值语句
- 消息语句
- 函数调用
- 函数原型
- 返回语句
交互
控制台 I/O
概念、底层原理
头文件
- 依赖于头文件
iostream
- 该头文件定义了处理输入的
istream类
和处理输出的ostream类
- 该头文件声明了一个名为cout的ostream对象,和名为cin的istream对象
- 该头文件的引用元素(cout、endl)使用名称空间
std
- 依赖于头文件
<<
运算符可以使用运算符
<<
来显示各种类型的数据,依赖于运算符重载的原理运算符重载:即一个符号可以有多种含义,这里的插入运算符
<<
和左移动运算符<<
写法一样,程序通过上下文判断含义非包裹形式:
<<
,表示该语句将字符串发送给cout
(流动式,而非用()
)
换行
endl
和\n
,均能换行,前者是控制符,后者是转移来的换行符
窗口补充
- 窗口环境不自动关闭:返回前加入
cin.get();
- 窗口环境不自动关闭:返回前加入
输出
- 输出成员函数
cout << ""
(本身)cout.put()
,输出单个字符cout.setf()
,清除小数的小数点后面的零
输入
- cin的常用成员函数
cin >> 变量
(本身)cin.get(name, arSize)
cin.getline(name, arSize)
cin.clear()
cin.eof()
、cin.fail()
- 每次读取多少(cin的成员函数)
cin
面向单词输入- 使用:
cin >> 变量
,使用空白(空格、制表符、换行符)确定字符串的结束位置,并丢弃空白、添加空字符 - 输入队列情况:连续读取的缺陷:空格只是结束、并不会结束输入阶段执行后面指令 在连续输入时,如果使用空格或制表符输入多个单词,这些单词会以此进入
输入队列
即:如果上一个输入接受了多个单词,会以此让下个输入接受多余的单词 比如:第一次输入Alistair Dreeb
,那么该次输入接受Alistair
,下一个输入跳过输入阶段,直接接受Dreeb
- 使用:
cin.get
面向行的输入(旧)使用:
cin.get(变量,arSize)
,使用换行符确定字符串的结束位置,但不丢弃换行符、在换行符之前添加空字符输入队列情况:在输入完一行后,
输入队列
中会有一个换行符,如果接着输入则会接受一个 头部有换行符的字符串 解决方案:使用一个不带参数的get把输入队列
中的换行符给处理掉,cin.get()
,为下次输入做好准备
cin.getline
面向行的输入(新)- 使用:
cin.getline(变量,arSize)
,使用换行符确定字符串的结束位置,并丢弃换行符、并添加空字符 - 输入队列情况:无多余字符串残留
- 使用:
get
与getline
区别cin.getline(变量,arSize);
等价于cin.get(变量,arSize);cin.get();
等价于cin.get(name, ArSize).get();
(链式调用)- 老版本并没有
getline()
get()
看起来麻烦,但检查错误更容易些,如:可以知道是否是因为遇到换行符才停止了读取,而非因为数组填满等原因
- 其他问题
- 赋值情况&数组越界:结束标记字符不是必然的,在输入语句赋值给非字符串时会自动截断。举例:
char ch; cin >> ch;
,输入字符不进行转换。当读入第一个字符后,停止该条输入语句,剩余字符进入输入队列int n; cin >> n;
,输入字符会转换为数字。当遇到非数字字符后,停止该条输入语句,剩余字符进入输入队列double x; cin >> x;
,输入字符自动转换为浮点。当遇到非浮点数字符后,停止该条输入语句,剩余字符进入输入队列char s[50]; cin >> s;
,输入字符不进行转换。当遇到空白字符后,停止该条输入语句,剩余字符进入输入队列 当输入字符过长,停止该条输入语句,剩余字符进入输入队列char s[50]; cin.getline(word,50);
,与上条基本相同 字符过长时该方法还会额外设置失效位(failbit)并关闭后面的输入
- 失效位的情况:
- 空行问题:当
get()
读取空行后会设置失效位并阻断后面的输入 - 数组越界问题:当数组越界,
getline()
方法会设置失效位并阻断后面的输入 - 恢复手段:可以用
cin.clear()
恢复输入
- 空行问题:当
- 赋值情况&数组越界:结束标记字符不是必然的,在输入语句赋值给非字符串时会自动截断。举例:
输入输出(与C不同)
输入输出:
编程语言 | C(弱类型) | C++(弱类型 - 强一点) | Python(强类型) | Java(强类型) |
---|---|---|---|---|
输入 | scanf("%d", &var) putchar() | cin >> var cin.get(变量,arSize) cin.getline(变量,arSize) | var=input() | |
保存方式 | 按格式保存 | 智能对象 | string类型 | |
—— | —————— | —————— | —————— | —————— |
输出 | printf("") getchar() | cout << "" (智能对象)cout.put() | print("") | System.out.println(“”) |
库的依赖 | 依赖于标准库<stdio.h> | 依赖于库<iostream> | 使用内置函数 | |
默认换行 | 否 | 否 | 是 | 是 |
智能转换 | 否,一般用格式化输出 | 是,cout << 1 | 是,print(1) | 是 |
字符拼接 | cout << '1' '1' | 直接+ 就行 | 直接+ 就行 | |
与数拼接 | #include <string.h> strcat('1',1); | cout << '1' << 1 | 直接+ 就行 | 直接+ 就行 |
文件 I/O
文件替代键盘输入(其实也是控制台 I/O)
gofish <fishtale
,这样程序将从fishtale文件(而非键盘)获取输入(<
是Unix和Windows命令提示符模式的重定向运算符)
文件尾条件
检测文件尾(EOF)
- (通常EOF被SACII编码后为-1,也可以此来检测检测)
- 检测到EOF后,cin将
eofbit
和failbit
都设置为1 cin.eof()
,可查看eofbit
是否被设置,是则返回turecin.fail()
,可查看failbit
或eofbit
是否被设置,是则返回ture
键盘可模拟文件尾条件:
- Unix:行首按下
Ctrl+D
- Windows:任意位置按下
Ctrl+Z 和 Enter
- Unix:行首按下
清除文件尾标记,使输入继续进行
- 使用
cin.clear()
- 使用
常用做法
- 一般不用
!cin.fail()
或!cin.eof()
而用cin.get(ch)
,后者可以检测其他失败原因(如磁盘故障) while (cin.get(ch)) {}
- 一般不用
cin.get(ch)
与ch=cin.get()
区别使用选择:前者可以使用链式调用,后者主要用于stdio.h转iostream时替换方便
属性 cin.get(ch)
ch=cin.get()
传递输入字符的方式 赋值给ch 将函数返回值赋给ch 用于字符输入时函数的返回值 istream对象(执行bool转换后为true) int类型的字符编码 到达EOF时函数的返回值 istream对象(执行bool转换后为false) EOF
简概
- 头文件
- 依赖于头文件
fstream
- 头文件定义了处理输出的
ofstream类
和处理输入的ifstream类
- 需要将文件和ofstream对象或ifstream对象关联起来。为此可以使用
open()
方法,并在使用后使用close()
关闭 - 使用名称空间
std
- ifstream也有
get()
、getline()
、eof()
、fail()
等方法
- 依赖于头文件
<<
运算符
输出
使用
主要步骤:(1) 头文件,(2) 创建一个ofstream对象,(3) 将该ofstream对象与一个文件关联起来,(4) 就像使用cout那样使用ofstream对象 (与cout相比多了第2、3步)
demo:
#include <fstream> ofstream fout; // 不叫fout也行 fout.open("fish.txt"); // 接受一个C-风格字符串作为参数(其可以是一个字面字符串,也可以是数组字符串) fout << "写入文件的内容" << endl; fout.close(); // 使用完应当关闭(防止同时写入同一文件/防止中途文件路径改变的设计?)
输入
使用
demo:
#include <fstream> ifstream fin; // 不叫fin也行 fin.open("fish.txt"); char filename[50]; fin >> filename; fin.close();
可能需要的检查
- 文件可能不存在或权限不足打不开,使用
ifstream对象.is_open()
判断,若文件打开成功则返回true (写在open()语句的后面) (较老编译器不支持则使用good()
来代替) - 读取文件不应超过EOF,使用
eof()
判断 - 可能遇到类型不匹配的情况,使用
fail()
判断(EOF时也返回true) - 文件受损或硬件故障,使用
bad()
或good()
判断
- 文件可能不存在或权限不足打不开,使用