C++ primer 5th 第8章 IO类
=====================================================================
第8章 IO类 278页
#ifdef DECLARATION
istream(输入流)类型,提供输入操作
ostream(输出流)类型,提供输出操作
cin,一个istream对象,从标准输入读取数据
cout,一个ostream对象,向标准输出写入数据
cerr,一个ostream对象,通常用于输出程序错误消息,写入到标准错误
>>运算符,用来从一个istream对象读取输入数据
<<运算符,用来向一个ostream对象写入输出数据
getline函数(参见3.3.2节,第78页)从一个给定的istream读取一行数据,
存入一个给定的string对象中
#endif
表8.1: IO库类型和头文件 | |
头文件 |
类型 |
iostream |
istream, wistream从流读取数据 |
ostream, wostream向流写入数据 | |
iostream, wiostream读写流 | |
fstream |
ifstream, wifstream从文件读取数据 |
ofstream, wofstream向文件写入数据 | |
fstream, wfstream读写文件 | |
sstream |
istringstream, wistringstream从string读取数据 |
ostringstream, wostringstream向string写入数据 | |
stringstream, wstringstream读写string |
=====================================================================
//QQ108201645编写
//读取第二行开始的数并相加
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;
ifstream &inputTest(ifstream& in)
{
char c=NULL;
while (c != '\n')
in.get(c);
return in;
}
double ToNum(ifstream& in, string& s)
{
double num;
while (in >> s)//循环给值
{
if (num = strtod(s.c_str(), NULL))//当是数字时自动返回1,把s里的数字字符串转换成double类型并传给num
break;
}
return num;//返回双精度浮点数
}
int main()
{
ofstream out("1.txt");
out << " abc 123 456" << endl;
out << " 张三 积分 54.7859 45.2141" << endl;
out.close();
ifstream in("1.txt");
if (!in)
cerr << "未发现文件" << endl;
inputTest(in);//略过一行
string s;
cout << ToNum(in, s) + ToNum(in, s) << endl;
in.close();
system("pause");
return 0;
}
=====================================================================
第8章 IO类 279页 IO流无拷贝或赋值
=====================================================================
//QQ108201645编写
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ofstream out1, out2;
#ifdef DECLARATION
out1 = out2;//错误,不能对流赋值
ofstream print(ofstream);//错误,不能初始化ofstream参数
out2 = print(out2);//错误,不能拷贝流对象
#endif
}
=====================================================================
第8章 IO类 122页
=====================================================================
//QQ108201645编写
表8.2: IO库条件状态 | |
strm::iostate |
strm是一种IO类型, 在表8.1(第278页)中已列出.iostate是一种机器相关的类型,提供了表达状态的完整功能 |
strm::badbit |
strm::badbit用来指出流已崩溃 |
strm::failbit |
strm::failbit用来指出一个IO操作失败了 |
strm::eofbit |
strm::eofbit用来指出流已到达文件结束 |
strm::goodbit |
strm::goodbit用来指出流未处于错误状态。此值保证为零 |
s.eof |
若流s的eofbit置位,则返回true |
s.fail |
若流s的failbit或badbit置位, 则返回true |
s.bad |
若流s的badbit置位,返回true |
s.good |
若流s处于有效状态, 则返回true |
s.clear() |
若流s中所有条件状态位复位,将流的状态设置为有效,返回void |
s.clear(flags) |
根据给定的flags标志位,将流s中对应条件状态位复位.flags的类型为strm::iostate. 返回void |
s.setstate(flags) |
根据给定的flags标志位,将流s中对应条件状态位复位.flags的类型为strm::iostate. 返回void |
s.rdstate |
返回流s的当前状态, 返回值类型为strm::iostate |
=====================================================================
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
istream& process_input(istream& is)
{
int num;
return is >> num;
}
int main()
{
int ival;
cin >> ival;
//如果输入Boo就会出错,ival对应int,但却得到B,这样就进入错误状态,如果输入一个文件结束标识符,也是错误的
auto old_state = cin.rdstate();//记住cin当前状态;
//rdstate成员返回一个iostate值,对应流的当前状态
cin.clear();//使cin有效
process_input(cin);//使用cin
cin.setstate(old_state);//将cin置为原有状态
//复位failbit和badbit,保持其他标志位不变
cin.clear(cin.rdstate()&~cin.failbit&~cin.badbit);
}
=====================================================================
#include <iostream>
using std::cin; using std::cout; using std::endl;
#include <sstream>
using std::istringstream;
#include <string>
using std::string;
void read()
{
// 设置badbit和eofbit,failbit
cin.setstate(cin.badbit | cin.eofbit | cin.failbit);
}
void off()
{
// 复位failbit和badbit,保持其它(eofbit)不变
cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit);
}
int main()
{
cout << "before read" << endl;
if (cin.good())
cout << "cin's good" << endl;
if (cin.bad())
cout << "cin's bad" << endl;
if (cin.fail())
cout << "cin's fail" << endl;
if (cin.eof())
cout << "cin's eof" << endl;
cout << "-----read------" << endl;
read();
cout << "after read" << endl;
if (cin.good())
cout << "cin's good" << endl;
if (cin.bad())
cout << "cin's bad" << endl;
if (cin.fail())
cout << "cin's fail" << endl;
if (cin.eof())
cout << "cin's eof" << endl;
cout<<"-----off------"<<endl;
off();
cout << "after off" << endl;
if (cin.good())
cout << "cin's good" << endl;
if (cin.bad())
cout << "cin's bad" << endl;
if (cin.fail())
cout << "cin's fail" << endl;
if (cin.eof())
cout << "cin's eof" << endl;
system("pause");
return 0;
}
=====================================================================
第8章 IO类 281页 练习题
=====================================================================
//QQ108201645编写
#include <iostream>
#include <stdexcept>
#include <string>
using namespace std;
/*
练习8.1:编写函数,接受一个istream&参数,返回值类型也是istream&。此函数
须从给定流中读取数据,直至遇到文件结束标识时停止。它将读取的数据打印在标准输
出上。完成这些操作后,在返回流之前,对流进行复位,使其处于有效状态。*/
istream& f(istream& in)
{
int v;
while (in>>v,!in.eof())//直到遇到文件结束符才停止读取
{
if (in.bad())
throw runtime_error("IO流错误");
if (in.fail())
{
cerr<<"数据错误,请重试"<<endl;
in.clear();
in.ignore(100, '\n');//清除以回车结束的输入缓冲区的内容
continue;
}
cout<<v<<endl;
}
in.clear();
return in;
}
//练习8.2:测试函数,调用参数为cin。
istream& fun(istream& input)
{
string s;
while (true)
{
input >> s;
if (input.eof())
break;
else
input.clear();
cout << s << '\n';
}
input.clear();
return input;
}
#ifdef DECLARATION
练习8.3:什么情况下,下面的while循环会终止?
while (cin >> i) /* ... */
当cin流bad、fail、eof时循环终止
#endif
int main()
{
cout<<"请输入整数,按Ctrl+z结束"<<endl;
f(cin);
cout<<"fun(cin):"<<endl;
fun(cin);
return 0;
}
=====================================================================
第8章 IO类 282页 管理输出缓冲
=====================================================================
//QQ108201645编写
#include <iostream>
#include <stdexcept>
#include <string>
using namespace std;
void print(ostream& os)
{
os << "please enter a value: ";
}
int main()
{
print(cout);
cout << "hi!" << endl;//输出hi和一个换行,然后刷新缓冲区
cout << "hi!" << flush;//输出hi,然后刷新缓冲区,不附加任何额外字符
cout << "hi!" << ends;//输出hi和一个空字符,然后刷新缓冲区
int ival;
cin >> ival;
cin.tie(&cout);//仅仅是展示,标准库将cin和cout关联在一起
//old_tie指向当前关联到cin的流(如果有的话)
ostream *old_tie = cin.tie(nullptr);//cin不再与其他流关联
//将cin与cerr关联;这不是一个好主意,因为cin应该关联到cout
cin.tie(&cerr);//读取cin会刷新cerr而不是cout
cin.tie(old_tie);//重建cin和cout间的正常关联
return 0;
}
=====================================================================
第8章 IO类 283页 文件输入输出
=====================================================================
//QQ108201645编写
表8.3: fstream特有的操作 | |
fstream fstrm |
创建一个未绑定的文件流.fstream是头文件fstream中定义的类型 |
fstream fstrm(s) |
创建fstream,并打开名为s的文件.s可以是string的类型,或者是一个指向C风格字符串的指针(参见3.5.4节,第109页).这些构造函数都是explicit的(参见7.5.4节,第265页).默认的文件模式mode依赖于fstream的类型 |
fstream fstrm(s, mode) |
与前一个构造函数类似,但按指定mode打开文件 |
fstrm.open(s) |
打开名为s的文件,并将文件与fstrm绑定. s可以是string的类型,或者是一个指向C风格字符串的指针.默认的文件mode依赖fstream的类型.返回void |
fstrm.close() |
关闭与fstrm绑定的文件.返回void |
fstrm.is_open() |
返回一个bool值,指出与fstrm关联的文件是否成功打开且尚未关闭 |
=====================================================================
第8章 IO类 284页 使用文件流对象
=====================================================================
//QQ108201645编写
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string ifile = "1.txt";//指定文件名与后缀。
ifstream in(ifile);//构造一个ifstream并打开文件
ofstream out;//输出文件流未关联到任何文件
in.close();//关闭文件
return 0;
}
=====================================================================
第8章 IO类 284页 用fstream代替iostream&读写文件
=====================================================================
//QQ108201645编写
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Sales_data
{
public://公有成员
//新增构造函数(不同的类内初始化方式)
// Sales_data() = default;//默认构造函数可以声明在类类部,也可以作为定义出现在类的外部
explicit Sales_data(const std::string &s, unsigned n, double p) :
bookNo(s), units_sold(n), revenue(p*n) {}
/*Sales_data(std::istream& is)
{
read(is, *this);
}*/
//保留默认构造函数
explicit Sales_data(std::string s = "")
:bookNo(s) {}//bookNo(s)表示构造函数列表初始化(构造函数初始值列表)
//只允许出现在类内声明构造函数时使用explicit
explicit Sales_data(std::istream& is)
{
read(is, *this);
}
friend Sales_data add(const Sales_data&, const Sales_data&);
friend std::istream& read(std::istream&, Sales_data&);
friend std::ostream& print(std::ostream&, const Sales_data&);
//添加一个文件流操作的友元
friend ifstream& read(ifstream& in, Sales_data& item)
{
double price = 0;
in >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return in;
}
friend ofstream& print(ofstream& out, const Sales_data& item)
{
out << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.ave_price();
return out;
}
friend std::istream& operator>>(std::istream& is, Sales_data&);//operator>>重载,支持cin>>对象名接收
friend std::ostream& operator<<(std::ostream& os, const Sales_data&);//operator<<重载,支持cin>>对象名直接输出内容
//之前已有的其它成员
std::string isbn() const;
Sales_data& combine(const Sales_data&);
private://私有成员
double ave_price()const;
std::string bookNo;
unsigned units_sold = 0;//c++11开始支持类体内初始化(变量名译:单独售出)
double revenue = 0.0;//初始化revenue(译:财政收入)
};//这里要加分号
Sales_data add(const Sales_data &lhs, const Sales_data& rhs)
{
Sales_data sum = lhs;//把lhs的数据拷贝给sum
sum.combine(rhs);//把rhs的数据成员加到sum当中
return sum;
}
//定义read和print函数
std::istream& read(std::istream& is, Sales_data& item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
std::ostream& print(std::ostream& os, const Sales_data& item)
{
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.ave_price();
return os;
}
//上面两个等同于operator>>与operator<<重载
std::istream& operator>>(std::istream& is, Sales_data& item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
std::ostream& operator<<(std::ostream& os, const Sales_data& item)
{
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.ave_price();
return os;
}
std::string Sales_data::isbn() const
{
//return bookNo;//用于返回Sales_data的数据成员
return this->bookNo;//同上
//默认情况this指针指向非常量的常量指针
}
//函数combine设计初衷类型复合赋值运算符+=
Sales_data& Sales_data::combine(const Sales_data& rhs)
{
units_sold += rhs.units_sold;//把rhs的成员加到this对象的成员上
revenue += rhs.revenue;
return *this;//返回调用该函数的对象
}
double Sales_data::ave_price()const
{
return units_sold ? revenue / units_sold : 0;
}
int main(int argc,char* argv[])
{
ifstream input(argv[1]);
ofstream output(argv[2]);
/*操作方法:首先在cpp编译exe所在目录(我的是vs2017路径C:\Users\Administrator\source\repos\01cpp\Debug)
新建一个1.txt
写入如下内容
09-99-999 5 6
09-99-999 9 12
写好并保存
然后再对这个文件夹shift+鼠标右键,调出此处dos命令窗口,我的文件是01cpp.exe
那就输入01cpp.exe 1.txt 2.txt,然后输出一个2.txt的结果
*/
Sales_data total;
if (read(input, total))
{
Sales_data trans;
while (read(input,total))
{
if (total.isbn() == trans.isbn())
total.combine(trans);
else
{
print(output, total);
total = trans;
}
}
print(output, total);
}
else
{
cerr<<"No data?!"<<endl;
}
return 0;
}
=====================================================================
第8章 IO类 285页 成员函数open与close
=====================================================================
//QQ108201645编写
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(int argc,char* argv[])
{
string ifile = "1.txt";
ifstream in(ifile);//创建一个ifstream(读取文件对象in)
ofstream out;//输出文件流未与任何文件关联
out.open(ifile + ".copy");//打开指定文件
//如果调用open失败,failbit会被置位,因为open可能失败,进行open检测
if (out)//检查是否成功
cout << "打开成功" << endl;
else
exit(1);//退出
in.close();//关闭文件
in.open(ifile + "2");//打开另一个文件
return 0;
}
=====================================================================
第8章 IO类 285页 自动构造与析构
=====================================================================
//QQ108201645编写
#include <iostream>
#include <fstream>
#include <string>
#include <stdexcept>
using namespace std;
void process(ifstream &is)
{
string s;
while (is >> s)
cout << s << endl;
}
int main(int argc, char* argv[])
{
// 对每个传递给程序的文件执行循环操作
for (auto p = argv + 1; p != argv + argc; ++p)
{
ifstream input(*p); // 创建输出流并打开文件
if (input)
{ // 如果文件打开成功,"处理"此文件
process(input);
}
else
cerr << "couldn't open: " + string(*p);
} // 每个循环步input都会离开作用域,因此会被销毁
auto p = argv + 1, end = argv + argc;
ifstream input;
while (p != end)
{ // 为每个文件传递给程序
input.open(*p); // 打开文件,自动清除流
if (input)
{ // 如果文件打开成功,"处理"此文件
process(input);
}
else
cerr << "couldn't open: " + string(*p);
input.close(); // 当我们完成它,关闭文件
++p; // 增加下一个文件指针
}
}
=====================================================================
第8章 IO类 285页 练习题
=====================================================================
//QQ108201645编写
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
/*
练习8.4:编写函数,以读模式打开一个文件,将其内容读入到一个string的vector
中,将每一行作为一个独立的元素存于vector中。*/
int main()
{
ifstream in("1.txt");//打开文件
if (!in)
{
cerr << "无法打开文件" << endl;
return -1;
}
string line;
vector<string> words;
while (getline(in, line))//从文件读取一行
{
words.push_back(line);//添加到vector中
}
in.close();//输入完毕,关闭文件
vector<string>::const_iterator it = words.begin();
while (it != words.end())//遍历vector
{
cout << *it << endl;//输出vector中的元素
++it;
}
system("pause");
return 0;
}
=====================================================================
//QQ108201645编写
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
/*练习8.5:重写上面的程序,将每个单词作为一个独立的元素进行存储。*/
int main(int argc,char* argv[])
{
vector<string> svec;
ifstream in_file(argv[1]);
if (in_file)
{
string s;
while (in_file>>s)
{
svec.push_back(s);
}
}
else
{
cerr<<"No file"<<endl;
return -1;
}
system("pause");
return 0;
}
=====================================================================
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
/*练习8.6:重写7.1.1节的书店程序(第229页),从一个文件中读取交易记录。将文件
名作为一个参数传递给main(参见6.2.5节,第196页)*/
class Sales_data
{
public://公有成员
//新增构造函数(不同的类内初始化方式)
// Sales_data() = default;//默认构造函数可以声明在类类部,也可以作为定义出现在类的外部
explicit Sales_data(const std::string &s, unsigned n, double p) :
bookNo(s), units_sold(n), revenue(p*n) {}
/*Sales_data(std::istream& is)
{
read(is, *this);
}*/
//保留默认构造函数
explicit Sales_data(std::string s = "")
:bookNo(s) {}//bookNo(s)表示构造函数列表初始化(构造函数初始值列表)
//只允许出现在类内声明构造函数时使用explicit
explicit Sales_data(std::istream& is)
{
read(is, *this);
}
friend Sales_data add(const Sales_data&, const Sales_data&);
friend std::istream& read(std::istream&, Sales_data&);
friend std::ostream& print(std::ostream&, const Sales_data&);
//添加一个文件流操作的友元
friend ifstream& read(ifstream& in, Sales_data& item)
{
double price = 0;
in >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return in;
}
friend ofstream& print(ofstream& out, const Sales_data& item)
{
out << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.ave_price();
return out;
}
friend std::istream& operator>>(std::istream& is, Sales_data&);//operator>>重载,支持cin>>对象名接收
friend std::ostream& operator<<(std::ostream& os, const Sales_data&);//operator<<重载,支持cin>>对象名直接输出内容
//之前已有的其它成员
std::string isbn() const;
Sales_data& combine(const Sales_data&);
private://私有成员
double ave_price()const;
std::string bookNo;
unsigned units_sold = 0;//c++11开始支持类体内初始化(变量名译:单独售出)
double revenue = 0.0;//初始化revenue(译:财政收入)
};//这里要加分号
Sales_data add(const Sales_data &lhs, const Sales_data& rhs)
{
Sales_data sum = lhs;//把lhs的数据拷贝给sum
sum.combine(rhs);//把rhs的数据成员加到sum当中
return sum;
}
//定义read和print函数
std::istream& read(std::istream& is, Sales_data& item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
std::ostream& print(std::ostream& os, const Sales_data& item)
{
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.ave_price();
return os;
}
//上面两个等同于operator>>与operator<<重载
std::istream& operator>>(std::istream& is, Sales_data& item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
std::ostream& operator<<(std::ostream& os, const Sales_data& item)
{
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.ave_price();
return os;
}
std::string Sales_data::isbn() const
{
//return bookNo;//用于返回Sales_data的数据成员
return this->bookNo;//同上
//默认情况this指针指向非常量的常量指针
}
//函数combine设计初衷类型复合赋值运算符+=
Sales_data& Sales_data::combine(const Sales_data& rhs)
{
units_sold += rhs.units_sold;//把rhs的成员加到this对象的成员上
revenue += rhs.revenue;
return *this;//返回调用该函数的对象
}
double Sales_data::ave_price()const
{
return units_sold ? revenue / units_sold : 0;
}
int main(int argc, char const *argv[])
{
ifstream input(argv[1]);
Sales_data total;
if (input >> total)
{
Sales_data trans;
while (input >> total)
{
if (total.isbn() == trans.isbn())
total.combine(trans);
else
{
print(cout, total) << endl;
total = trans;
}
}
print(cout, total) << endl;
}
else
{
cerr << "No data?!" << endl;
return -1;
}
system("pause");
return 0;
}
=====================================================================
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
/*练习8.6:重写7.1.1节的书店程序(第229页),从一个文件中读取交易记录。将文件
名作为一个参数传递给main(参见6.2.5节,第196页)*/
class Sales_data
{
public://公有成员
//新增构造函数(不同的类内初始化方式)
// Sales_data() = default;//默认构造函数可以声明在类类部,也可以作为定义出现在类的外部
explicit Sales_data(const std::string &s, unsigned n, double p) :
bookNo(s), units_sold(n), revenue(p*n) {}
/*Sales_data(std::istream& is)
{
read(is, *this);
}*/
//保留默认构造函数
explicit Sales_data(std::string s = "")
:bookNo(s) {}//bookNo(s)表示构造函数列表初始化(构造函数初始值列表)
//只允许出现在类内声明构造函数时使用explicit
explicit Sales_data(std::istream& is)
{
read(is, *this);
}
friend Sales_data add(const Sales_data&, const Sales_data&);
friend std::istream& read(std::istream&, Sales_data&);
friend std::ostream& print(std::ostream&, const Sales_data&);
//添加一个文件流操作的友元
friend ifstream& read(ifstream& in, Sales_data& item)
{
double price = 0;
in >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return in;
}
friend ofstream& print(ofstream& out, const Sales_data& item)
{
out << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.ave_price();
return out;
}
friend std::istream& operator>>(std::istream& is, Sales_data&);//operator>>重载,支持cin>>对象名接收
friend std::ostream& operator<<(std::ostream& os, const Sales_data&);//operator<<重载,支持cin>>对象名直接输出内容
//之前已有的其它成员
std::string isbn() const;
Sales_data& combine(const Sales_data&);
private://私有成员
double ave_price()const;
std::string bookNo;
unsigned units_sold = 0;//c++11开始支持类体内初始化(变量名译:单独售出)
double revenue = 0.0;//初始化revenue(译:财政收入)
};//这里要加分号
Sales_data add(const Sales_data &lhs, const Sales_data& rhs)
{
Sales_data sum = lhs;//把lhs的数据拷贝给sum
sum.combine(rhs);//把rhs的数据成员加到sum当中
return sum;
}
//定义read和print函数
std::istream& read(std::istream& is, Sales_data& item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
std::ostream& print(std::ostream& os, const Sales_data& item)
{
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.ave_price();
return os;
}
//上面两个等同于operator>>与operator<<重载
std::istream& operator>>(std::istream& is, Sales_data& item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
std::ostream& operator<<(std::ostream& os, const Sales_data& item)
{
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.ave_price();
return os;
}
std::string Sales_data::isbn() const
{
//return bookNo;//用于返回Sales_data的数据成员
return this->bookNo;//同上
//默认情况this指针指向非常量的常量指针
}
//函数combine设计初衷类型复合赋值运算符+=
Sales_data& Sales_data::combine(const Sales_data& rhs)
{
units_sold += rhs.units_sold;//把rhs的成员加到this对象的成员上
revenue += rhs.revenue;
return *this;//返回调用该函数的对象
}
double Sales_data::ave_price()const
{
return units_sold ? revenue / units_sold : 0;
}
int main(int argc, char const *argv[])
{
argv[1] = "1.txt";
ifstream input(argv[1]);
Sales_data total;
if (input >> total)
{
Sales_data trans;
while (input>> trans)
{
if (total.isbn() == trans.isbn())
total.combine(trans);
else
{
print(cout, total) << endl;
total = trans;
}
}
print(cout, total) << endl;
}
else
{
cerr << "No data?!" << endl;
return -1;
}
system("pause");
return 0;
}
=====================================================================
第8章 IO类 286页 文件模式
=====================================================================
//QQ108201645编写
表8.4: 文件模式 | |
in |
以读方式打开 |
out |
以写方式打开 |
app |
每次写操作前均定位到文件末尾 |
ate |
打开文件后立即定位到文件末尾 |
trunc |
截断文件 |
binary |
二进制方式进行IO |
#ifdef DECLARATION
只可以对ofstream或fstream对象设定out模式
只可以对ifstream或fstream对象设定in模式
只有当out也被设定时才可设定trunc模式
只要trunc没被设定,就可以设定app模式。在app模式下,即使没有显式指定
out模式,文件也总是以输出方式打开
默认情况下,即使我们没有指定trunc,以out模式打开的文件也会被截断.为了保留
以out模式打开文件的内容,我们必须同时指定app模式,这样只会将数据追加写到
文件末尾;或者同时指定in模式,即打开文件同时进行读写操作(参见17.5.3节,第676页)
将介绍对同一个文件既进行输入又进行输出的的方法
ate和binary模式可用于任何类型的文件流对象,且可以与其他任何文件模式组合使用
#endif
=====================================================================
第8章 IO类 286页 文件模式
=====================================================================
//QQ108201645编写
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char const *argv[])
{
ofstream out1("file1");//隐含输出模式打开文件并截断文件
ofstream out2("file1", ofstream::out);//隐含的截断文件
ofstream out3("file1", ofstream::out | ofstream::trunc);
//为了保留文件内容,我们必须显式指定app模式
ofstream app("file1", ofstream::app);//隐含为输出模式
ofstream app2("file1", ofstream::out | ofstream::app);
out1.close();
out2.close();
out3.close();
app.close();
app2.close();
system("pause");
ofstream out;//未指定文件打开模式
out.open("scratchpad");//模式隐含设置为输出和截断
out.close();//关闭out以便我们将其用于其他文件
out.open("precious", ofstream::app);//输出模式与追加
out.close();
return 0;
}
=====================================================================
第8章 IO类 287页 练习题
=====================================================================
//QQ108201645编写
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
class Sales_data
{
public://公有成员
//新增构造函数(不同的类内初始化方式)
// Sales_data() = default;//默认构造函数可以声明在类类部,也可以作为定义出现在类的外部
explicit Sales_data(const std::string &s, unsigned n, double p) :
bookNo(s), units_sold(n), revenue(p*n) {}
/*Sales_data(std::istream& is)
{
read(is, *this);
}*/
//保留默认构造函数
explicit Sales_data(std::string s = "")
:bookNo(s) {}//bookNo(s)表示构造函数列表初始化(构造函数初始值列表)
//只允许出现在类内声明构造函数时使用explicit
explicit Sales_data(std::istream& is)
{
read(is, *this);
}
friend Sales_data add(const Sales_data&, const Sales_data&);
friend std::istream& read(std::istream&, Sales_data&);
friend std::ostream& print(std::ostream&, const Sales_data&);
friend ifstream& read(ifstream& in, Sales_data& item)
{
double price = 0;
in >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return in;
}
friend ofstream& print(ofstream& out, const Sales_data& item)
{
out << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.ave_price() << endl;
return out;
}
friend std::istream& operator>>(std::istream& is, Sales_data&);//operator>>重载,支持cin>>对象名接收
friend std::ostream& operator<<(std::ostream& os, const Sales_data&);//operator<<重载,支持cin>>对象名直接输出内容
//之前已有的其它成员
std::string isbn() const;
Sales_data& combine(const Sales_data&);
private://私有成员
double ave_price()const;
std::string bookNo;
unsigned units_sold = 0;//c++11开始支持类体内初始化(变量名译:单独售出)
double revenue = 0.0;//初始化revenue(译:财政收入)
};//这里要加分号
Sales_data add(const Sales_data &lhs, const Sales_data& rhs)
{
Sales_data sum = lhs;//把lhs的数据拷贝给sum
sum.combine(rhs);//把rhs的数据成员加到sum当中
return sum;
}
//定义read和print函数
std::istream& read(std::istream& is, Sales_data& item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
std::ostream& print(std::ostream& os, const Sales_data& item)
{
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.ave_price() << endl;
return os;
}
//上面两个等同于operator>>与operator<<重载
std::istream& operator>>(std::istream& is, Sales_data& item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
std::ostream& operator<<(std::ostream& os, const Sales_data& item)
{
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.ave_price();
return os;
}
std::string Sales_data::isbn() const
{
//return bookNo;//用于返回Sales_data的数据成员
return this->bookNo;//同上
//默认情况this指针指向非常量的常量指针
}
//函数combine设计初衷类型复合赋值运算符+=
Sales_data& Sales_data::combine(const Sales_data& rhs)
{
units_sold += rhs.units_sold;//把rhs的成员加到this对象的成员上
revenue += rhs.revenue;
return *this;//返回调用该函数的对象
}
double Sales_data::ave_price()const
{
return units_sold ? revenue / units_sold : 0;
}
/*
练习8.6:重写7.1.1节的书店程序(第229页),从一个文件中读取交易记录。将文件名作为一
个参数传递给main(参见6.2.5节,第196页)
操作方法:首先在cpp编译exe所在目录
(我的是vs2017路径C:\Users\Administrator\source\repos\01cpp\Debug)
新建一个1.txt
写入如下内容
9-999-99 6 7
9-999-99 7 7
9-999-98 5 8
写好并保存
然后再对这个文件夹shift+鼠标右键,调出此处dos命令窗口,我的文件是01cpp.exe
那就输入01cpp.exe 1.txt
控制台将输出
9-999-99 13 91 7
9-999-98 5 40 8
*/
int main(int argc, char *argv[])
{
if (argc != 2)
{
cerr<<"请给出输入,输出文件名"<<endl;
return -1;
}
ifstream in(argv[1]);
if (!in)
{
cerr<<"无法打开文件"<<endl;
return -1;
}
Sales_data total;
if (read(in, total))
{
Sales_data trans;
while (read(in,trans))
{
if (total.isbn() == trans.isbn())
total.combine(trans);
else
{
print(cout, total);
total = trans;
}
}
print(cout, total);
}
else
{
cerr<<"No data"<<endl;
return -1;
}
return 0;
}
=====================================================================
//QQ108201645编写
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
class Sales_data
{
public://公有成员
//新增构造函数(不同的类内初始化方式)
// Sales_data() = default;//默认构造函数可以声明在类类部,也可以作为定义出现在类的外部
explicit Sales_data(const std::string &s, unsigned n, double p) :
bookNo(s), units_sold(n), revenue(p*n) {}
/*Sales_data(std::istream& is)
{
read(is, *this);
}*/
//保留默认构造函数
explicit Sales_data(std::string s = "")
:bookNo(s) {}//bookNo(s)表示构造函数列表初始化(构造函数初始值列表)
//只允许出现在类内声明构造函数时使用explicit
explicit Sales_data(std::istream& is)
{
read(is, *this);
}
friend Sales_data add(const Sales_data&, const Sales_data&);
friend std::istream& read(std::istream&, Sales_data&);
friend std::ostream& print(std::ostream&, const Sales_data&);
friend ifstream& read(ifstream& in, Sales_data& item)
{
double price = 0;
in >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return in;
}
friend ofstream& print(ofstream& out, const Sales_data& item)
{
out << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.ave_price() << endl;
return out;
}
friend std::istream& operator>>(std::istream& is, Sales_data&);//operator>>重载,支持cin>>对象名接收
friend std::ostream& operator<<(std::ostream& os, const Sales_data&);//operator<<重载,支持cin>>对象名直接输出内容
//之前已有的其它成员
std::string isbn() const;
Sales_data& combine(const Sales_data&);
private://私有成员
double ave_price()const;
std::string bookNo;
unsigned units_sold = 0;//c++11开始支持类体内初始化(变量名译:单独售出)
double revenue = 0.0;//初始化revenue(译:财政收入)
};//这里要加分号
Sales_data add(const Sales_data &lhs, const Sales_data& rhs)
{
Sales_data sum = lhs;//把lhs的数据拷贝给sum
sum.combine(rhs);//把rhs的数据成员加到sum当中
return sum;
}
//定义read和print函数
std::istream& read(std::istream& is, Sales_data& item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
std::ostream& print(std::ostream& os, const Sales_data& item)
{
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.ave_price() << endl;
return os;
}
//上面两个等同于operator>>与operator<<重载
std::istream& operator>>(std::istream& is, Sales_data& item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
std::ostream& operator<<(std::ostream& os, const Sales_data& item)
{
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.ave_price();
return os;
}
std::string Sales_data::isbn() const
{
//return bookNo;//用于返回Sales_data的数据成员
return this->bookNo;//同上
//默认情况this指针指向非常量的常量指针
}
//函数combine设计初衷类型复合赋值运算符+=
Sales_data& Sales_data::combine(const Sales_data& rhs)
{
units_sold += rhs.units_sold;//把rhs的成员加到this对象的成员上
revenue += rhs.revenue;
return *this;//返回调用该函数的对象
}
double Sales_data::ave_price()const
{
return units_sold ? revenue / units_sold : 0;
}
/*
练习8.8:修改上一题的程序,将结果追加到给定的文件末尾。对同一个输出文件,运
行程序至少两次,检验数据是否得以保留。
操作方法:首先在cpp编译exe所在目录
(我的是vs2017路径C:\Users\Administrator\source\repos\01cpp\Debug)
新建一个1.txt
写入如下内容
9-999-99 6 7
9-999-99 7 7
9-999-98 5 8
写好并保存
然后再对这个文件夹shift+鼠标右键,调出此处dos命令窗口,我的文件是01cpp.exe
那就输入01cpp.exe 1.txt 2.txt回车后再次输出
控制台无输出,运行两次后,2.txt将在末尾追加结果
*/
int main(int argc, char *argv[])
{
if (argc != 3)
{
cerr<<"请给出输入,输出文件名"<<endl;
return -1;
}
ifstream in(argv[1]);
if (!in)
{
cerr<<"无法打开输出文件"<<endl;
return -1;
}
ofstream out(argv[2],ofstream::app);
if (!out)
{
cerr << "无法打开输出文件" << endl;
return -1;
}
Sales_data total;
if (read(in, total))
{
Sales_data trans;
while (read(in,trans))
{
if (total.isbn() == trans.isbn())
total.combine(trans);
else
{
print(out, total);
total = trans;
}
}
print(out, total);
}
else
{
cerr<<"No data"<<endl;
return -1;
}
return 0;
}
=====================================================================
第8章 IO类 287页 string流
表8.5:stringstream特有的操作 | |
sstream strm |
strm是一个未绑定的stringstream对象。sstream是头文件sstream中定义的一个类型 |
sstream strm(s) |
strm是一个sstream对象,保存string s的一个拷贝。此构造函数是explicit的(参见7.5.4节,第265页) |
strm.str() |
返回strm所保存的string的拷贝 |
strm.str(s) |
将string s拷贝到strm中。返回void |
=====================================================================
第8章 IO类 288页 使用istringstream
=====================================================================
#include<sstream>
#include<string>
#include<iostream>
using namespace std;
int main()
{
/*istringstream从string读取数据(类似ifstream),ostringstream从string写入数据(类似ofstream),stringstream既可以读数据,也可以写数据(类似fstream)*/
string s = "abc 123 hello world", out;
istringstream isg("测试 123 abc 测试");
cout << "1 isg格式化输出:" << isg.str() << endl << endl;
isg.clear();//重复使用字符串流时,每次都要调用clear
isg.str(s);
isg >> out;//读取到string的out对象
cout << "out = " << out << endl;//打印输出
isg >> out;
cout << "out = " << out << endl;
isg >> out;
cout << "out = " << out << endl;
isg >> out;
cout << "out = " << out << endl;
isg >> out;
cout << "2 isg格式化输出:" << isg.str() << endl << endl;
ostringstream msg;
msg << "哈 你好 123 abc" << endl;//写入字符串
cout << "1 msg格式化输出:" << msg.str() << endl;//格式化输出
msg.clear();
msg.str(s);//把s存入msg
cout << "2 msg格式化输出:" << msg.str() << endl << endl;
msg << "内容 打印";
cout << "3 msg格式化输出:" << msg.str() << endl << endl;
msg.str("");//清空数据
msg.clear();//clear() 方法只是重置了stringstream的状态标志,并没有清空数据。
out = "123";
msg << out;
out = " abc";
msg << out;
out = " hello world";
msg << out;
cout << "4 msg格式化输出:" << msg.str() << endl << endl;
system("pause");
return 0;
}
=====================================================================
//QQ108201645编写
#include<iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
struct PersonInfo
{
string name;
vector<string> phones;
};
int main()
{
string line, word;//分别保存来自输入的一行和单词
vector<PersonInfo> people;//保存来自输入的所有记录
//遂行从输入读取数据,直至cin遇到文件尾(或其他错误)
while (getline(cin,line))
{
PersonInfo info;//创建一个保存此记录数据的对象
istringstream record(line);//将记录绑定到刚读入的行
//假设line="张三 13500000000"
//则info.name="张三"
//再把第二个传给word,然后放入info.phones的vector
record >> info.name;//读取名字
while (record>>word)//读取电话号码
{
info.phones.push_back(word);//保存它们
}
people.push_back(info);//将此记录追加people末尾
}
system("pause");
return 0;
}
=====================================================================
第8章 IO类 289页 练习题
=====================================================================
//QQ108201645编写
#include<iostream>
#include <sstream>
#include <string>
using namespace std;
/*练习8.9:使用你为8.1.2节(第281页)第一个练习所编写的函数打印一个istringstream对象的内容。*/
istream& f(istream& in)
{
string v;
while (in >> v, !in.eof())
{
if (in.bad())
throw runtime_error("IO流错误");
if (in.fail())
{
cerr << "数据错误,请重试" << endl;
in.clear();//防止fail和bad
in.ignore(100, '\n');
continue;
}
cout<<v<<endl;
}
in.clear();
return in;
}
int main()
{
ostringstream msg;
msg << "C++ Primer 第五版" << endl;
istringstream in(msg.str());// 返回in所保存的string的拷贝
f(in);
system("pause");
return 0;
}
=====================================================================
//QQ108201645编写
#include<iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
/*练习8.10:编写程序,将来自一个文件中的行保存在一个vector中。然后
使用一个istringstream从vector读取数据元素,每次读取一个单词。*/
int main()
{
string line;
vector<string> words;
while (getline(cin, line))//从文件读取一行
{
words.push_back(line);//添加到vector中
}
in.close();
vector<string> ::const_iterator it = words.begin();//迭代器
while (it!=words.end())//遍历vector
{
istringstream line_str(*it);
string word;
while (line_str>>word)//通过istringstream从vector中读取数据
{
cout << word << " ";
}
cout<<endl;
++it;
}
system("pause");
return 0;
}
=====================================================================
//QQ108201645编写
#include<iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
/*练习8.11:本节的程序在外层while循环中定义了istringstream 对象。如果
record 对象定义在循环之外,你需要对程序进行怎样的修改?重写程序,将record
的定义移到while循环之外,验证你设想的修改方法是否正确*/
class PersonInfo
{
public:
string name;
vector<string> phones;
};
int main()
{
string line, word;//创建string两个对象
vector<PersonInfo> people;//创建一个存放类类型的vector,用来保存输入的所有记录
istringstream record;
while (getline(cin, line))//读取一行存放line
{
PersonInfo info;//创建一个保存记录的对象
record.clear();//重复使用字符串流时,每次都要调用clear
record.str(line);//绑定line
record >> info.name;//读取名字,把第一个空格前的字符串传给info.name
while (record >> word)//读取电话号码,把第二个空格前的字符串传给word
info.phones.push_back(word);//再把word的字符串放入info.phones
people.push_back(info);//将记录追加到末尾
}
system("pause");
return 0;
}
=====================================================================
第8章 IO类 289页 使用ostringstream
=====================================================================
//QQ108201645编写
#include<iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
class PersonInfo
{
public:
string name;
vector<string> phones;
};
bool valid(const string &s)
{
return true;
}
string format(const string &s)
{
return s;
}
vector<PersonInfo> getData(istream &is)
{
string line, word;//创建string两个对象
vector<PersonInfo> people;//创建一个存放类类型的vector,用来保存输入的所有记录
istringstream record;
while (getline(cin, line))//读取一行存放line
{
PersonInfo info;//创建一个保存记录的对象
record.clear();//重复使用字符串流时,每次都要调用clear
record.str(line);//绑定line
record >> info.name;//读取名字,把第一个空格前的字符串传给info.name
while (record >> word)//读取电话号码,把第二个空格前的字符串传给word
info.phones.push_back(word);//再把word的字符串放入info.phones
people.push_back(info);//将记录追加到末尾
}
return people;
}
ostream& process(ostream &os, vector<PersonInfo> people)
{
for (const auto &entry : people)//对people中每一项
{
ostringstream formatted, badNums;//每个循环步创建的对象
for (const auto& nums : entry.phones)//对应PersonInfo中vector<string> phones的每个string对象
{
if (!valid(nums))
badNums << " " << nums;//将数的字符串形式存入badNums
else
formatted << " " << format(nums);//format(nums)连同空格写入到formatted
}
if (badNums.str().empty())//没有错误的数
os << entry.name << " "//打印名字
<< formatted.str() << endl;//和格式化的数
else//否则打印错误的名字
cerr << "input error : " << entry.name
<< " invalid number(s) " << badNums.str() << endl;
}
return os;
}
int main()
{
process(cout, getData(cin));
system("pause");
return 0;
}
=====================================================================
第8章 IO类 289页 练习题
=====================================================================
//QQ108201645编写
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
//练习8.13:重写本节的电话号码程序,从一个命名文件而非cin读取数据。
class PersonInfo
{
public:
string name;
vector<string> phones;
};
bool valid(const string &s)
{//17章介绍如何验证电话号码,现在只返回true
return true;
}
string format(const string &s)
{
return s;
}
int main()
{
ofstream file_("people.txt",ios::out|ios::binary);
//创建文件people,以写入方式打开,二进制方式
if (!file_)
cerr<<"未发现文件"<<endl;
file_<<"abc 123 456"<<endl;//写入字符串
file_ << "hello 456 789" << endl;//写入第二行字符串
file_.close();//关闭
ifstream file("people.txt");//cpp目录下新建一个people.txt并输入abc 123保存或默认使用上面的代码创建文件
if (!file)
{
cerr << "No file" << endl;
return -1;
}
string line, word;
vector<PersonInfo> people;
while (getline(file,line))
{
PersonInfo info;
istringstream record(line);
record >> info.name;
while (record>>word)
{
info.phones.push_back(word);
}
people.push_back(info);
}
//读取完后关闭文件
file.close();
for (const auto &entry : people)
{
ostringstream formatted, badNums;
for (const auto &nums : entry.phones)
{
if (!valid(nums))
badNums << " " << nums;
else
{
formatted << " " << format(nums);
}
}
if (badNums.str().empty())
cout<<entry.name<<" "<<formatted.str()<<endl;
else
{
cerr<<" input error: "<<entry.name<<" invalid number(s) "<<badNums.str()<<endl;
}
}
/*练习8.14:我们为什么将entry和nums定义为 const auto& ?
一是避免拷贝,二是防止改变它们。*/
system("pause");
return 0;
}
=====================================================================
//改写成迭代器
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
using namespace std;
class PersonInfo
{
public:
string name;
vector<string> phones;
};
bool vaild(const string& s)
{
return true;
}
string format(const string &s)
{
return s;
}
int main()
{
ofstream outfile("people.txt");
if (!outfile)
cerr << "未发现文件,并创建" << endl;
outfile << "张三 135 13801" << endl;
outfile << "李四 186 1330" << endl;
outfile.close();
ifstream infile("people.txt");
if (!infile)
{
cerr << "未发现文件,退出" << endl;
exit(1);//退出
}
string line, word;
vector<PersonInfo> people;
istringstream record;
while (getline(infile, line))
{
PersonInfo info;
record.clear();
record.str(line);
record >> info.name;
while (record >> word)
info.phones.push_back(word);
people.push_back(info);
}
//读取完关闭
infile.close();
for (vector<PersonInfo>::const_iterator entry = people.begin();
entry != people.end(); ++entry)
{
ostringstream formatted, badNums;
for (vector<string>::const_iterator nums = entry->phones.begin();
nums != entry->phones.end(); ++nums)
{
if (!vaild(*nums))
badNums << " " << *nums;
else
formatted << " " << format(*nums);
}
if (badNums.str().empty())
cout << entry->name << " " << formatted.str() << endl;
else
cerr << " input error: " << entry->name << " invalid number(s) " << badNums.str() << endl;
}
system("pause");
return 0;
}
=====================================================================
//改写for循环
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
class PersonInfo
{
public:
string name;
vector<string> phones;
};
bool valid(const string& s)
{
return true;
}
string format(const string& s)
{
return s;
}
vector<PersonInfo> getdata(istream& s)
{
string line, word;
vector<PersonInfo> people;
istringstream record;
cout<<"输入一行内容,如果输入end则结束"<<endl;
while (getline(cin,line)&&line!="end")
{
PersonInfo info;
record.clear();//清除内容
record.str(line);//绑定line
record >> info.name;
while (record>>word)
{
info.phones.push_back(word);
}
people.push_back(info);
cout << "输入一行内容,如果输入end则结束" << endl;
}
return people;
}
ostream& process(ostream& os, vector<PersonInfo> people)
{
for (size_t i = 0; i < people.size(); i++)
{
ostringstream formatted, badNums;
for (size_t j = 0; j < people[i].phones.size(); j++)
{
if (!valid(people[i].phones[j]))
badNums << " " << people[i].phones[j];
else
formatted << " " << format(people[i].phones[j]);
}
if (badNums.str().empty())
os << people[i].name << " " << formatted.str() << endl;
else
os<<"input error: "<<people[i].name<< " "<<badNums.str()<<endl;
}
return os;
}
int main()
{
process(cout, getdata(cin));
system("pause");
return 0;
}
=====================================================================
#include <fstream>
#include <time.h>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
#pragma warning(disable:4996)
size_t nums = 1;
string RetTime()
{//获取系统时间
time_t timep;//创建timep对象
time(&timep);//获取系统时间,返回一个指针
/*time_t time(time_t *seconds) 返回自纪元 Epoch(1970-01-01 00:00:00 UTC)起经过的时间,
以秒为单位。如果 seconds 不为空,则返回值也存储在变量 seconds 中。
seconds -- 这是指向类型为 time_t 的对象的指针,用来存储 seconds 的值。*/
char tmp[64];
struct tm * p = localtime(&timep);
// cout<<asctime(p)<<endl;//把时间转成字符串
strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", p);
//格式化结构 *p 表示的时间,并把它存储在 tmp 中。最大字符数为sizeof(tmp)
return tmp;
}
void DeleteFileRow()
{
ifstream infile("1.txt");
if (!infile)
cerr << "未发现文件并创建" << endl;
string line;
vector<string> svec;
while (getline(infile,line))
{
svec.push_back(line);
}
infile.close();
size_t flag = 0;
while (svec.size() > 9)
{
svec.erase(svec.begin());
flag = 1;
}
if (flag == 1)
{
ofstream out("1.txt");
if (!out)
{
cerr << "未发现文件" << endl;
return;
}
for (auto i : svec)
{
out.write(i.c_str(), i.size());
out << endl;//因为读取时不会读到行数,所以直接加一个换行
}
out.close();
}
}
void GetLog()
{
DeleteFileRow();
ofstream out("1.txt", ios::out | ios::binary | ios::app);
if (out.fail())
cerr << "未发现文件" << endl;
string buf = RetTime();
out << "(" << nums++ << ") " << buf.c_str() << endl;
out.close();
}
int main()
{
cout << "错误信息" << endl;
while (true)
{
GetLog();
}
system("pause");
return 0;
}
=====================================================================
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
bool Gline_(ifstream& fin,string& s)
{
char c[1024]{ 0 };
size_t i = 0;
while (!fin.eof())
{
fin.get(c[i]);
if (c[i] == '\n')
{
i = -1;
break;
}
i++;
}
s = c;
return !fin.eof();//返回是否结束
}
int main()
{
ofstream open("1.txt");
if(open.fail())
cerr<<"未发现文件"<<endl;
open << "abcqqq 123" << endl;
open << "bcd 123" << endl;
open.close();
ifstream in("1.txt");
vector<string> svec;
/*=====================================================================*/
//假设用getline将会少了换行符
/*string line;
while (getline(in,line))
{
svec.push_back(line);
}*/
/*=====================================================================*/
/*char c[1024]{ 0 };
size_t i = 0;
while (!in.eof())
{
in.get(c[i]);
if (c[i]== '\n')
{
svec.push_back(c);
i = -1;
memset(c, 0, 1024);
}
i++;
}*/
/*=====================================================================*/
//自定义Gline_实现
string line;
while (Gline_(in,line))
{
svec.push_back(line);
}
/*=====================================================================*/
in.close();
open.open("2.txt");
for (auto i : svec)
{
cout << i.size() <<" "<<i;//长度与内容
open.write(i.c_str(), i.size());
}
open.close();
system("pause");
return 0;
}
=====================================================================