C++学习笔记

Streams#

  • getline(cin, name)是从cin中读取到下一个换行字符的段落到name中(不含换行字符本身),cin >> name则是从cin中读取到下一个空白字符的段落到name中。
  • getInteger的实现 example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
int getInteger(string &prompt) {
int n;
string text;
cout << prompt; // 将提示符输出
cin >> text; // 获取用户输入
istringstream iss(text); // 创建输入流
if(iss >> n) {
return n;
} else {
cout << "输入错误" << endl;
return -1;
} // 读取整数
}
  • getInteger的实现 课程解, 自行注释解释
1
2
3
4
5
6
7
8
9
10
11
12
13
int getInteger(const string& prompt) { // const表示设定prompt为常量, &表示引用
while (true) { // 建立while循环, 若读取不成功则重新读取
cout << prompt; // 弹出提示词
string line; // 初始化line变量
if (!getline(cin, line)) // 从用户输入中将一行文字读取到line, !取反表示若不成功则...
throw domain_error(...); // 抛出错误, if语句在后面没有大括号时会将下一行列为代码块
istringstream iss(line); // 初始化输入流,内容为line

int result; char trash; // 初始化读取到的结果和垃圾变量
if (iss >> result && !(iss >> trash)) // 若读取到整数结果, 且整数后面没有读入到任何字符
return result; // 返回读取到的整数
}
}
  • 不能将提取运算符与getline混用: 提取运算符在提取数字时只会将位置设到数字末尾而不会忽略\n等换行符, 会导致后续getline函数只能读取到空白内容。使用while(!getline())以多次读取或cin.ignore()忽略换行符能够解决。

  • size_t类型变量: 专门用于存储大小的量,其最大长度取决于long类型(2^32-1 || 2^64-1)
  • 创建类型的别名 using new_name = old_name
  • auto类型变量由编译器自行确定变量需要的类型
  • 必须使用auto的情况: 无需关心/不知晓确切的返回值属性时。不能为函数参数使用auto类型。
  • 使用auto类型变量时, 现代编译器会告诉你参数的类型。
  • auto在多返回值时具有自动形成列表的优势。(ep. vector)

Today’s challenge#

Problem#

1
2
3
4
5
// Write the following function which prompts the user for a filename, opens the ifstream to the file, reprompt if the filename is not valid and then return the filename.

string promptUserForFile(ifstream& stream, string prompt = "", string reprompt = "") {
// your implementation here
}

Solution#

1
2
3
4
5
6
7
8
9
10
11
12
13
// Write the following function which prompts the user for a filename, opens the ifstream to the file, reprompt if the filename is not valid and then return the filename.

string promptUserForFile(ifstream& stream, string prompt = "", string reprompt = "") {
while (true) {
cout << prompt; // 提示用户输入文件名
string filename; // 初始化文件名变量
getline(cin, filename); // 读入文件名
if(stream.open(filename)) {
return filename;
}
cout << reprompt << endl;
}
}