参考
cin与cin.get的用法
https://www.cnblogs.com/geeksongs/p/10644721.html
读取数量不定的数据
#include<iostream>
using namespace std;
int main()
{
int val;
int sum = 0;
while (cin >> val) {
sum += val;
}
cout << sum << endl;
return 0;
}
读取未知数量的string对象
#include<bits/stdc++.h>
using namespace std;
int main()
{
string word;
while (cin >> word) { // 反复读取,直至到达文件末尾,一遇到换行符就输出
cout << word << endl; // 换行符输出,逐个输出单词,每个单词后面紧跟一个换行符
}
return 0;
}
如果流有效,即没有遇到文件结束标记或者非法输入,那么执行while内部操作。
使用getline读入一整行
适用场景:最终得到的字符串中保留空白符时
和输入运算符一样,geline也会返回他的流参数,可以使用他的返回值作为条件。
#include<bits/stdc++.h>
using namespace std;
int main()
{
string line;
// getline函数从输入流中读取内容,知道遇到换行符为止(换行符也读取进来了),
// 然后把读取到的内容存到string对象(line)中(不存换行符)
while (getline(cin, line)) {
cout << line << endl; // getline只要遇到换行符就结束读取并返回结果
}
return 0;
}
string 流应用
(1) 当某些工作是对整行文本进行处理,而其他工作是处理行内的单个单词时,通常可以使用istringsteam
#include<iostream>
#include<vector>
#include<string>
#include<sstream>
using namespace std;
int main()
{
struct PersonInfo {
string name;
vector<string> phones;
};
string line, word; // 分别保存来自输入的一行和单词
vector<PersonInfo> people; // 保存来自输入的所有记录
// 逐行从输入读取数据,直至cin遇到文件尾或其他错误
while (getline(cin, line)) {
PersonInfo info; // 创建保存每行记录数据的对象
istringstream record(line); // 创建istringsteam对象,从string对象中读入数据
record >> info.name; // 从istringsteam对象record中提取name
while (record >> word) { // 从istringsteam对象record中提取号码,当全部读取后,出发“文件结束符”,在record上的下一个输入操作就会失败
info.phones.push_back(word);
}
people.push_back(info); // 将每行的记录追加到people末尾
cout << people.back().name << " " << people.back().phones[0] << endl;
}
}
(2) stringstream 有效处理空格问题(忽略空格)
#include<iostream>
#include<stack>
#include<string>
#include<sstream>
using namespace std;
class Solution {
public:
string reverseWords(string s)
{
stack<string> stk;
stringstream ss(s);
string tmp, res;
while (ss >> tmp) { // 当s中所有字符串都读取完后触发"文件结束信号"
stk.push(tmp);
cout << "enter while" << endl;
stk.push(" ");
}
if (!stk.empty()) { // 当s为空时,while循环一次也没进入,此时stk空
stk.pop(); // 首先弹出stack中最后一个单词后的空格
}
while (!stk.empty()) {
res += stk.top(); // string 使用push_back(a),a为char类型
stk.pop();
}
return res;
}
};
(3) 一个单词转换的map【C++Primer第11章 】
//
// Created by j on 2021/9/25.
//
#include <iostream>
#include <string>
#include <map>
#include <fstream>
#include <sstream>
using namespace std;
//单词转换函数
const string word_Transform(ifstream &map_file, ifstream &input);
//读入规则文件,生成对应的map映射
map<string, string> buildMap(ifstream &map_file);
//转换操作
const string &Transform(const string &word, const map<string, string> &map);
int main()
{
ifstream file_stream("D:\\code\\clion_Project\\files\\file.txt"); //待转换的文件,ifstream从文件中读取数据
ifstream map_stream("D:\\code\\clion_Project\\files\\rule.txt"); //规则文件,创建文件流并与文件绑定
const string result = word_Transform(map_stream, file_stream);
cout << result;
return 0;
}
const string word_Transform(ifstream &map_file, ifstream &input)
{
string result = "";
map<string, string> trans_map = buildMap(map_file);
string line;
// 每次读入一行待转换的文本
while (getline(input, line)) {
stringstream ss(line); // 创建istringsteam对象,从string对象中读入数据
string word;
bool first_word = true; // 控制是否打印空格
// 每次取这行文本中的一个单词
while (ss >> word) {
if (first_word) {
first_word = false;
}
else {
result += " "; // 在单词间打印一个空格
}
// 转换每个单词
result += Transform(word, trans_map);
}
result += '\n';
}
return result; // 完成一行的转换
}
// 读入规则文件,生成对应的map映射
map<string, string> buildMap(ifstream &map_file)
{
map<string, string> trans_map; //保存转换规则的map
string key; //键
string value; //值
string line;
// 读取第一个单词到key,剩下的所有内容读入value
while (map_file >> key && getline(map_file, value)) {
if (value.size() > 1) { // 如果有一个号码则大于1(空格加一个有效的号码)
trans_map[key] = value.substr(1); // 跳过前导空格(getline会读入前面的空格,遇到换行符结束)
}
else {
throw runtime_error("no rule for " + key);
}
}
return trans_map;
}
//转换操作
const string &Transform(const string &word, const map<string, string> &map)
{
auto map_iter = map.find(word);
if (map_iter != map.cend()) {
return map_iter->second;
}
else {
return word;
}
}