跳至主要內容

交互

LincZero大约 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),使用换行符确定字符串的结束位置,并丢弃换行符、并添加空字符
      • 输入队列情况:无多余字符串残留
    • getgetline区别

      • 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将eofbitfailbit都设置为1
    • cin.eof(),可查看eofbit是否被设置,是则返回ture
    • cin.fail(),可查看failbiteofbit是否被设置,是则返回ture
  • 键盘可模拟文件尾条件:

    • Unix:行首按下Ctrl+D
    • Windows:任意位置按下Ctrl+Z 和 Enter
  • 清除文件尾标记,使输入继续进行

    • 使用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()判断