1.输入流
代码实现:
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
std::cout << "Enter some integers - enter Ctrl+Z to end.\n";
//一个输入流迭代器从 cin 中读取 int 类型的值
std::istream_iterator<int> iter{std::cin};
std::istream_iterator<int> copy_iter{iter};
std::istream_iterator<int> end_iter;
int sum {};
//第一个循环会求出所有用输入流迭代器读入的值的和,直到识别出 EOF 状态,
//它是通过从流中读取 Ctrl+Z 标志设置的
while(iter != end_iter)
{
sum += *iter++;
}
std::cout << "Total is " << sum << std::endl;
//一句代替for循环
//std::cout << "Total is " << accumulate(iter, end_iter, 0) <<std::endl;
//必须调用流对象的 dear() 来重置 EOF 标志
std::cin.clear();
//需要跳过输入缓冲区中留下的 '\n' 字符,通过调用流对象的 ignore 做到
std::cin.ignore();
std::cout << "Enter some more integers - enter Ctrl+Z to end.\n";
int product{1};
//读取值并计算它们的 product
//乘积
while(true)
{
if(copy_iter == end_iter)
break;
product *= *copy_iter++;
}
std::cout << "product is " << product << std::endl;
//必须调用流对象的 dear() 来重置 EOF 标志
std::cin.clear();
//需要跳过输入缓冲区中留下的 '\n' 字符,通过调用流对象的 ignore 做到
std::cin.ignore();
std::vector<double> data;
std::cout <<"Enter some numerical values — enter Ctrl+Z to end.\n";
std::copy(std::istream_iterator<double>{std::cin}, std::istream_iterator <double>{},
std::back_inserter(data));
std::copy(std::begin(data), std::end(data), std::ostream_iterator <double>{std::cout, " "});
std::cout << std::endl;
}
结果显示:
三种输出流方式:
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <string>
using std::string;
int main()
{
// 3 种方式将 words 容器中的元素写到标准输出流中
std::vector<string> words {"The", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog"};
//out_iter1 流迭代器通过调用只以输出流为参数的构造函数而生成。第一个循环以常规方式输出迭代器符号,
//在解引用后递增它,并复制 word 的当前值到 out_iter1 的解引用的结果中。循环后面的语句会在流中写一个新行。
std::ostream_iterator<string> out_iter1{std::cout};
for(const auto& word : words)
{
*out_iter1++ = word;
*out_iter1++ = " ";
}
*out_iter1++ = "\n";
//为了保证应用分隔符的第二条赋值语句有输出迭代器作为它的左操作数,语句中的括号是必要的。
for(const auto& word : words)
{
(out_iter1 = word) = " ";
}
out_iter1 = "\n";
//元素 的值会被复制到 out_iter2 中,定义它的构造函数的第二个参数指定了每个输出值后面的分隔符字符串。
std::ostream_iterator<string> out_iter2 {std::cout, " "};
std::copy(std::begin(words), std::end(words), out_iter2);
out_iter2 = "\n";
}
结果显示:
代码实例:
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <string>
using std::string;
class Name
{
private:
std::string first_name{};
std::string second_name{};
public:
Name() = default;
Name(const std::string first, const std::string second):first_name{first}, second_name {second} {}
friend std::istream& operator>>(std::istream& in, Name& name);
friend std::ostream& operator<<(std::ostream& out, const Name& name);
};
inline std::istream& operator>>(std::istream& in, Name& name)
{ return in >> name.first_name >> name.second_name; }
inline std::ostream& operator<<(std::ostream& out, const Name& name)
{ return out << name.first_name << ' ' << name.second_name; }
int main()
{
std::cout << "Enter names as first_name second_name. Enter Ctrl+Z on a separate line to end:\n";
std::vector<Name> names {std::istream_iterator<Name> {std::cin},std::istream_iterator<Name>{}};
//copy() 算法会将 Name 对象复制到输出流迭代器标识的目的位置,这个迭代器会将对象写到标准输出流中。
std::copy(std::begin(names),std::end(names) , std::ostream_iterator<Name> {std::cout," "});
}
结果显示:
表示文件流的类模板:
用下面这些定义在 ios_base 类中的常量的组合来指定它们的打开状态:
代码实例:
#include <iostream>
#include <fstream>
#include <iterator>
#include <string>
#include <set>
#include <vector>
#include <algorithm>
using std::string;
int main()
{
string file_in {"/home/lyy/OpenCV3/STL/流迭代器/file.txt"};
std::ifstream in {file_in};
if(!in)
{
std::cerr << file_in << " not open." << std::endl;
exit(1);
}
//set 容器会以升序保存单词,并且这个容器中的每个单词都有自己的 key
std::set<string> dictionary {std::istream_iterator<string>(in), std::istream_iterator<string>()};
std::cout << dictionary.size() << " words in dictionary." << std::endl;
std::vector<string> words;
string word;
//words 容器中包含从 cin 中输入的单词的字谜。
//每一个单词都在 while 循环的第一个 if 表达式中读取
while(true)
{
std::cout << "\nEnter a word, or Ctrl+z to end: ";
//调用流对象的 eof(),当输入 Ctrl+Z 时,eof() 会返回 true。
if((std::cin >> word).eof())
break;
string word_copy {word};
//
do
{ //对于每次排列,包括第一次,都调用 count() 来确定这个单词是否在 dictionary 容器中
if(dictionary.count(word))
words.push_back(word);
//输入的单词的字符重排列
std::next_permutation(std::begin(word), std::end(word));
} while(word != word_copy);//当排列返回原始单词时,do-while 循环结束
std::copy(std::begin(words), std::end(words), std::ostream_iterator<string>{std::cout, " "});
std::cout << std::endl;
//如果期望每次出现 8 个字谜,需要使用循环来生成多行输出
size_t count {}, max {8};
for (const auto& wrd : words)
std::cout << wrd << ((++count % max == 0) ? '\n' : ' ');
words.clear();
}
in.close();
}
结果显示:
#include <iostream>
#include <fstream>
#include <iterator>
#include <string>
using std::string;
int main()
{
//从输入文件复制单词到输出文件,以空格隔开输出的单词。这个程序总会覆盖输出文件的内容
string file_in {"/home/lyy/OpenCV3/STL/流迭代器/file.txt"};
std::ifstream in {file_in};
if(!in)
{
std::cerr << file_in << " not open." << std::endl;
exit(1);
}
string file_out {"/home/lyy/OpenCV3/STL/流迭代器/file_copy.txt"};
std::ofstream out {file_out};
//为了确保能够用流迭代器准确地复制原文件,必须一个字符一个字符地读文件,并阻止 >> 运算符忽略空格
std::copy(std::istream_iterator<char>{in >> std::noskipws},
std::istream_iterator<char>{},std::ostream_iterator<char> {out});
in.clear();
std::cout << "Original file length: " << in.tellg() << std::endl;
std::cout << "File copy length: " << out.tellp() << std::endl;
in.close();
out.close();
}
结果显示: