/****** PersonInfo.h *********/
#ifndef _DATA_PEOPLE
#define _DATA_PEOPLE
#include<iostream>
#include <string>
#include <vector>
#include <stdexcept>
#include <iomanip>
using namespace std;
class PersonInfo
{
public:
PersonInfo() = default;
PersonInfo(string _name, string _phone1, string _phone2, string _phone3) :m_name(_name),
m_phone_number{_phone1,_phone2,_phone3 } {}; //数组的初始化是用花括号
private:
string m_name;
vector<string> m_phone_number;
//m_phone_number[1]=("das");
};
#endif // !_DATA_PEOPLE
/****** Nodefalut.h *********/
#include<iostream>
#include <string>
#include <vector>
#include <stdexcept>
#include <iomanip>
using namespace std;
class _my_data
{
public:
_my_data(int _month,int _day,int _year):m_month(_month), m_day(_day), m_year(_year){};
_my_data()= default;
int getMonth()const {
return m_month;
}
int getDay()const {
return m_day;
}
int getYear()const {
return m_year;
}
/* 很显然这个函数不能是成员函数,因为第一个参数必须是输出流类ostream,
为了让输出流支持链式表达式,
所以函数返回ostream的引用,如果要输入的数据是Date类的私有成员,
可以将这个函数设置为Date类的友元函数 */
friend ostream &operator<<(ostream& os, const _my_data& d)
{
char fillc = os.fill('0'); //可以使用setfill('char x')使用x来填充空下的空格
//设置填充字符,当输出长度小于指定的长度的时候用于进行填充
os << setw(2) << d.getDay() << '-' //setw是在输出时分配了n个字符的输出宽度,然后默认的是在n个字符宽度中右对齐输出
<< setw(2) << d.getMonth() << '-'
<< setw(4) << setfill(fillc) << d.getYear();
//setfill还原回原来的填充字符
return os;
}
friend istream &operator>>(istream& is, _my_data& d);
private:
int m_month;
int m_day;
int m_year;
};
istream &operator>>(istream& is, _my_data& d)
{
char fillc = is.fill('0');
is >> setw(2)>>d.m_day;
char _dash;
is >> _dash;
if (_dash != '-') //ios是基类
is.setstate(ios::failbit); ////设置流错误状态,这使得下面的所有操作都会被忽略
is >> setw(2)>>d.m_month;
is >> _dash;
if (_dash != '-')
is.setstate(ios::failbit);
is >> setw(4)>> setfill(fillc) >>d.m_year;
return is;
}
/****** main.cpp *********/
#include<iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <sstream>
#include "Nodefalut.h"
#include "PersonInfo.h"
/*
比如:istream iss;
string _koo;
iss >> _koo; 看箭头的意思,是从iss中写入东西,然后给_koo;
ostream oss;
oss << _koo; 是_koo中的东西写入oss;然后用oss来读出来
*/
#define MAX_LINE 2048
using namespace std;
void main(int argc, char *argv[])
{
string line("l");
string word;
word = line + "9"; //竟然还有这种操作
//cout << word;
//istringstream iss("t h i s "); //给iss赋初值
//相当于给word读取值,并且是一个一个string的读取t是一个string,
//while (iss >> word) //s是一个string...;有多少给多少
//cout << word << "#";
//输出的是t#h#i#s#
// _my_data s(2,22,2019);
//cout<<s; //神奇
//cout << (cout,s); //二者是一样的
string file_name(argv[1]);
const char *input = file_name.c_str();
std::ifstream is(file_name, fstream::in);
vector<string> cow_contents;
if (is.fail())
{
fprintf(stderr, "Error in opening file %s\n", input);
return;
}
char buffer;
string words;
string::size_type w_size=0;//不要忘记初始化
//ifstream每次读的时候读到空格才会读下一个,也就是一个字符串读一次
//看了网上的代码,有更简洁的版本
while (is>>words)
{
cow_contents.push_back(words); //两行就搞定了,哎,我真的?
}
/*
while (is.get(buffer)) //如果buffer是string类型,赋值给buffer,一直获取每一行的string,直到没有,
{ //不加while,则只读取一行
//如果是get();则是char类型,一次只读取一个字符,也是读到没有,
//但也会根据文件内容自动转行
if (!isspace(buffer)) //不是空格时,则一直往words里塞,直到遇到空格等不是字母或数字
{
if (words.size() == 0)
{
words = buffer;
}
else {
words += buffer;
}
}
else {
cow_contents.push_back(words); //当遇到空格时,把之前的words.push进vector里面
words.clear(); //然后清空words,选择下一个单词push进
}
}
cow_contents.push_back(words); //最后一个单词加进去,因为最后一个单词结束之后,直接结束,
*/
//for(auto &c: cow_contents) //else里的push_back没有执行,所以最后一个单词还得在外面push一次
//cout << c<<endl;
is.close(); //必须在这里关闭文件,不然下面得写入“baemax”,会写两遍
std::ofstream os(file_name, fstream::app);
//is.open(file_name, fstream::app| fstream::out);
string hi = "hi baemax";
os << endl<< "baemax"; //如果要写进去,则必须用ofstream 来写,即使前面是fstream也不行,即重新定义一个os
//is.write(hi.c_str(), hi.size());
os.close();
os.close(); //如果读书文件,在这里关闭的话,则写入baemax,还会写进is打开的text中,即写了两遍
std::ofstream _os("file.txt", fstream::out); //如果想要创建一个新的文件,且写入,则需要给一个新定义的名字
_os << endl << "baemax"; //并且是写入ofstream
_os.close();
string k,k1,k2;
istringstream strm("dasd fasd gdsafsdbj fdsf"); //神奇的是istream并不能进行拷贝和赋值;
//但ifstream和istringstream却可以
strm >> k; //并且他们两个还可以记住其输出的(读取的状态)
cout << k << endl; //比如:istringstream strm("dasd fasd gdsafsdbj fdsf");
strm >> k1; //strm >> k;把空格前的第一个读到k中去,
cout << k1; //此时strm的状态是在fasd开始的位置,
//如果要再次读出strm;strm >> k1;则k1是fasd;
//然后状态此时又在变到下一个字符串开始的位置
cout<<strm.str(); //print dasd
strm.str("dasdf"); //将dasdf拷贝到strm中去
string name;
//好好理解下面这段代码
while (getline(cin, line))
{
istringstream iss;
iss.str(line) ;
iss >> name;
while (iss >> word)
cout << word << "#";
cout << endl;
}
ifstream file2_open("C:\\Users\\信计捡球员\\Desktop\\测试\\测试\\file_name2.txt", ifstream::in);
vector<string> _phones;
string _data_line;
//好好理解下面这段代码
istringstream _iss;
while (getline(file2_open, _data_line))
{
string p_name;
string phones;
_iss.str(_data_line);
_iss >> p_name;
cout << p_name<<" ";
while (_iss >> phones)
cout << phones<<" ";
_phones.push_back(phones);
cout << endl;
_iss.clear(); //如果不给他的状态复位(clear),
//它里面原来是张三 10086 100087 10088
//此时,它的状态是在10088后面,你只是把它的str(即内容)换成了
//李四 10001 10002 10003
//此时它的状态还是在10003后面,还是在最后,输出的还是空白
//所以我用clear给它复位,使它的状态回到最前边,即原始状态
} //你可以把istringstream _iss;放里面,这样就不会出现这样的
//问题,因为每次都是新的
system("pause");
}
目前c++先学到这,后续用其数据结构和算法来弥补其编程能力;然后边写,边学后面的知识(用到再学);
我的时间并不多,重点还是在工作的方向上