Можете привести примеры чтения и записи вектора через операторы << и >>?
я просто пока плохо представляю как это реализовать..
допустим вот для этого пример :
class Team
{
public :
friend ostream& operator << (ostream& outs, const vector<Team>&);
friend istream& operator >> (istream& sin, vector<Team>&);
friend void file_save(const vector<Team>&);
private:
string TeamName;
int win;
int lose;
int draw;
int score;
};
ostream& operator << (ostream& outs, const vector<Team>& v)
{
outs << "Team " << " Wins " << "Loses " << "Draws " << "Scores\n";
for (unsigned int i=0;i<v.size();i++)
{
outs << v[i].TeamName;
set_spaces_t(v,i);
outs << v[i].win << " " << v[i].lose << " " << v[i].draw << " " << v[i].score << "\n";
}
return outs;
}
void file_save(const vector<Team>& v){
char filename[15];
cout <<"Enter a file name(without extension) : ";
cin >> filename;
//filename=filename+".sys";
ofstream outfile(filename);
outfile << v;
}
А зачем, собственно, тебе перегружать операцию ввода/вывода именно для вектора? Это чем-то обосновано? Почему не перегрузить именно для класса, и не читать/добавлять в вектор, пока не достигнем конца файла?
Кстати, пример файла, из которого читаются данные, можно привести?
ну как видно по коду,он так же будет создан не правильно,ибо туда вводиться все то,что выводит оператор << для класса Team.
Это грубо не правильно,и я это понимаю.Я только решил попробывать.Хм..тоесть ,читать объект,потом делать push_back к этому объекту?в цикле читать..хм..просто я хотел написать метод,который бы читал сразу весь вектор..
Ну, так напиши себе метод (скажем, такой:
class Team {
public:
file_read(ifstream& fin, vector<Team>& vt);
...
};
хм..сейчас попробую.Кстате,вопрос такой : почему дружественные функции не нарушают принципы инкапсуляции?
Ещё один : почему нельзя для outfile передавать имя файла как string?только чар?а если я хочу что бы пользователь не задавал расширение файла,мне же проще будет написать так :
string filename;
cout <<"Enter a file name(without extension) : ";
cin >> filename;
filename=filename+".sys";
ofstream outfile(filename);
Потому, что дружественная функция - это часть интерфейса класса, определяемая разработчиком, а не пользователем, а значит, при правильном использовании дружественных функций, никто ИЗВНЕ доступа туда, куда не надо не получит...
string filename;?
cout <<"Enter a file name(without extension) : ";
cin >> filename;
filename=filename+".sys";
ofstream outfile(filename.c_str(), ios::out);
хм..спасибо=)
Написал тут кое-что..только почему-то не хочеть работать..
вот функция сохранения в файл :
void file_save(const vector<Team>& v){
char filename[15];
cout <<"Enter a file name(without extension) : ";
cin >> filename;
//filename=filename+".sys";
ofstream outfile(filename);
for (unsigned int i=0;i<v.size();i++)
outfile << v[i].TeamName <<v[i].win <<v[i].lose << v[i].draw << v[i].score; ;
}
void file_read (vector<Team>& v)
{
Team temp_obj;
char filename[15];
cout << "Input file name : ";
cin >> filename;
ifstream infile(filename);
for (unsigned int i=0;i<v.size();i++)
{
infile >> temp_obj.TeamName >> temp_obj.win >> temp_obj.lose >> temp_obj.draw >> temp_obj.score;
//cout << " here!" << temp_obj.TeamName;
v.push_back(temp_obj);
}
}
Спасибо и в этот раз...надо всетаки нормально в Лафоре прочитать про потоки и файлы..
Добавлено через 13 мин.
бжж..опять..
Функции :
void file_save(const vector<Team>& v){
string filename;
cout <<"Enter a file name(without extension) : ";
cin >> filename;
filename=filename+".sys";
ofstream outfile(filename.c_str(), ios::out);
for (unsigned int i=0;i<v.size();i++)
outfile << v[i].TeamName <<v[i].win <<v[i].lose << v[i].draw << v[i].score; ;
}
void file_read (vector<Team>& v)
{
Team temp_obj;
string filename;
cout << "Input file name : ";
cin >> filename;
filename=filename+".sys";
ifstream infile(filename.c_str());
while (!infile.eof()&& infile.good())
{
infile >> temp_obj.TeamName >> temp_obj.win >> temp_obj.lose >> temp_obj.draw >> temp_obj.score;
cout <<temp_obj.TeamName;
v.push_back(temp_obj);
}
}
Я ж тебя просил привести пример файла, из которого читаешь информацию... Или показывай, как заполняешь вектор данными, чтобы можно было проверить именно на том файле, который записывается через file_save()...
содержимое файла :
team11236team21236
while (!infile.eof()&& infile.good())
{
infile >> temp_obj.TeamName >> temp_obj.win >> temp_obj.lose >> temp_obj.draw >> temp_obj.score;
cout <<temp_obj.TeamName;
v.push_back(temp_obj);
}
Нет, так не пойдет... Надо разделять данные... Хотя бы пробелами
Смотри:
team.h
#ifndef TEAM_H_
#define TEAM_H_
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Team
{
friend ostream& operator << (ostream&, const Team& );
friend istream& operator >> (istream&, Team& );
public:
string TeamName;
int win;
int lose;
int draw;
int score;
Team ();
};
// Это - НЕ метод класса, не нужно инициализировать лишний объект,
// чтобы через него вызывать эту функцию.
void file_read(vector<Team>&);
#endif /*TEAM_H_*/
...
ostream& operator << (ostream& os, const Team& ob)
{
os << ob.TeamName << " " << ob.win << " " << ob.lose <<
" " << ob.draw << " " << ob.score;
return os;
}
istream& operator >> (istream& is, Team& ob)
{
int ch; // <--- Добавлено
getline(is, ob.TeamName, ' ');
is >> ob.win >> ob.lose >> ob.draw >> ob.score;
while(is && (ch = is.get()) != '\n'); // <--- Добавлено
return is;
}
void file_read(vector<Team>& vt) {
// Хотя вот это я бы сделал ДО вызова file_read(), и передавал
// бы сюда уже именно открытый поток ввода, как и показал выше
string filename;
cout <<"Enter a file name(without extension) : ";
cin >> filename;
filename = filename + ".txt";
ifstream infile(filename.c_str(), ios::in);
Team t;
while(infile >> t) {
vt.push_back(t);
}
infile.close();
}
vector<Team> vt;
int main() {
file_read(vt); // Читаем
// Проверяем
for(vector<Team>::iterator it = vt.begin(); it != vt.end(); it++) {
cout << *it << endl;
}
return 0;
}
Спасибо за помощь!Но всеравно не много не понимаю пока..ну разберусь.У меня теперь новый вопрос
Допустим,имеется какой-то класс с полями int и string.И есть вектор этих объектов v.
Я хочу отсортировать вектор с помощью алгоритма sort() по заданным параметрам,т.е сортировка по i (в порядке возрастания,или убывания), сортировка по str (так же,в порядке возрастания и убывания).Понятно,что для этих типов определен оператор < и оператор >. Но,если я просто вызову функция sort(v.begin(),v.end()); ,то будет ошибка.Так вот, надо ли мне,определять предикат сортировки для каждого из параметров?
Допустим вот так :
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
class c{
public :
int c;
string str;
};
bool sortbystr(const c& first,const c& second)
{
return (first.str==second.str);
}
int main() {
vector<c> v;
sort(v.begin(),v.end(),sortbystr);
return 0;
}
class Team
{
public :
string TeamName;
};
class Player
{
public :
long int salary;
string Lname;
string team;
};
class Team {
...
string get_team_name() const {
return TeamName;
}
}
struct check
{
string st;
bool operator() (const Team& t) const {
return (t.get_team_name() == st);
}
check(string s): st(s) {
}
};
...
vector<Team> vt;
string team; // наличие этой строки в vt будем проверять
cin >> team;
vector<Team>::iterator found;
found = find_if(vt.begin(), vt.end(), check(team)); // Собственно, поиск
// Проверяем, нашлось что-то или нет:
if(found != vt.end()) {
cout << "найдено: " << *found << endl;
}
else {
cout << "не найдено" << endl;
}
...
Ну я отсутствовал в инете пару дней..когда ты сказал проще самому написать,я написал..Только почему-то циклиться,а почему - не пойму.Возможно гдето-то с параметрами напутал..вот такая картина :
void input_p (vector<Player>& v,const vector<Team>& vt)
{
cout <<"Input number of Player's to add : ";
int j;
cin >> j;
Player ob;
for (int k=0;k<j;k++)
AddOne_p(v,ob,vt);
}
void AddOne_p (vector <Player>& v,Player ob, const vector<Team>& vt)
{
cout <<"Input Player last name : ";
cin >> ob.Lname;
cout <<"\nInput team name, in which Player play : ";
while(exsist_c(ob.club,vt))
cin >> ob.club;
cout << "\nInput Player salary : ";
cin >> ob.salary;
v.push_back(ob);
}
bool exsist_c (string& club ,const vector<Team>& vt ) {
bool ye=0;
for (unsigned int i=0;i<vt.size();i++)
{
if(club==vt[i].TeamName)
ye=1;
else
{
cout <<"Entered team does not exsist";
ye=0;
}
}
return ye;
}
Насколько я вижу - вот так будет лучше:
bool exsist_c (string& club, const vector<Team>& vt ) {Это первое... Второе - вопрос на засыпку: зачем ты передаешь ob в AddOne_p()? Можно же не тянуть его извне, а описывать прямо внутри этой функции, ты ж все равно не пользуешься (да и не сможешь, передается-то объект не по ссылке, а по значению) введенными данными в самой функции input_p()...
for(unsigned int i = 0; i < vt.size(); i++) {
if(club == vt[i].TeamName) return 1;
}
cout <<"Entered team does not exsist"; // Это можно делать только после просмотра всего вектора
return 0;
}