Войти

Показать полную графическую версию : файлы


farik
24-05-2006, 06:49
Есть программа:

#include <iostream.h>
#include <algorithm>
#include <fstream>
#include <string>
#include <iterator>
#include <functional>
#include <windows.h>
#include<istream.h>
using namespace std;

void RussianMessage(char *message){
char rmessage[256];
CharToOem(message,rmessage);
cout<<rmessage;
}

int RussianMenu(){
RussianMessage("\nВведите 1 для добавления новой структуры в файл\n");
RussianMessage("Введите 2 для показа всех структур из файла\n");
RussianMessage("Введите 3 для поиска\n");
RussianMessage("Введите 4 для выхода\n");
int choice;
cin>>choice;
return choice;
}


class Man{

struct Data {
Data() : age(0) {}
// переменная для возраста
int age;
// переменная для имени
std::string name;
// переменная для фамилии
std::string surname;

friend ofstream& operator << (ofstream& stream, const Data& d)
{
// Записываем возраст
stream<<d.age<<' ';
// Записываем имя
stream<<d.name.c_str()<<' ';
// Записываем фамилию
stream<<d.surname.c_str()<<' ';
return stream;

}

friend fstream& operator << (fstream& stream, const Data& d)
{

RussianMessage("\nИмя: ");
stream<<d.name.c_str();

RussianMessage("\nФамилия: ");
stream<<d.surname.c_str();

RussianMessage("\nВозраст: ");
stream<<d.age;
return stream;

}

friend istream& operator >> (istream& stream, Data& d)
{
stream>>d.age;
stream>>d.name;
stream>>d.surname;

return stream;
}


};

struct Pred:binary_function<Data,std::string, bool> {

Pred(){}

bool operator () (const Data& d, std::string str) const
{
return ( d.surname == str)? true : false;

}
};


Data data_;

public:
// конструктор с параметрами
Man(char *n,char *s,int a);
// конструктор
Man();
// функция ввода данных
void Put();
// функция показа данных
void Show();
// функция сохранения в файл
void SaveToFile();
// функция показа содержимого файла
void ShowFromFile();
void SearchFile();

};
// конструктор
Man::Man(){}

// конструктор с параметрами
Man::Man(char *n,char *s,int a){
data_.name.assign(n);
data_.surname.assign(s);
data_.age = a;
}



// функция ввода данных
void Man::Put(){
std::string temp;
RussianMessage("\nВведите имя:\n");
cin>>temp;

data_.name.assign(temp);


RussianMessage("\nВведите фамилию:\n");
cin>>temp;

data_.surname.assign(temp);

RussianMessage("\nВведите возраст\n");
cin>>data_.age;
}

// функция сохранения в файл
void Man::SaveToFile(){

ofstream file("c:\\men.txt",ios::out|ios::app);
if(!file){
RussianMessage("Файл не открылся для чтения !!!");
exit(1);
}

file<<data_;
}

void Man::SearchFile()
{
std::string surname;

fstream file("C://men.txt",ios::in);
if(!file){
RussianMessage("Файл не открылся для чтения !!!");
exit(1);
}

istream_iterator<Data> first(file), last , pos;

RussianMessage("Введите фамилию:");
cin>>surname;

pos = std::find_if(first,last,bind2nd(Pred(),surname));

if(pos == last)
RussianMessage("\nТакого сотрудника нет!\n");
else
cout<<*pos;


}

// функция показа содержимого файла
void Man::ShowFromFile(){
fstream file("C://men.txt",ios::in);
if(!file){
RussianMessage("Файл не открылся для чтения !!!");
exit(1);
}

istream_iterator<Data> first(file), last;

copy(first,last, ostream_iterator<Data>(cout,"\n"));

}
int main(){

Man a;
do{
switch(RussianMenu()){

case 1: // Добавление записи
a.Put();
a.SaveToFile();
break;
case 2: // Показ всех записей
a.ShowFromFile();
break;
case 3:
a.SearchFile();
break;
case 4:// Прощание с пользователем
RussianMessage("До Свидания\n");
return 0;
default: // Неправильный ввод
RussianMessage("Неверный Ввод\n");
}

}while(1);


}




Она выдает ошибки:
error C2678: binary '>>' : no operator defined which takes a left-hand operand of type 'class istream_withassign' (or there is no acceptable conversion)
error C2678: binary '>>' : no operator defined which takes a left-hand operand of type 'class istream_withassign' (or there is no acceptable conversion)
error C2678: binary '>>' : no operator defined which takes a left-hand operand of type 'class istream_withassign' (or there is no acceptable conversion)
error C2678: binary '<<' : no operator defined which takes a left-hand operand of type 'class ostream_withassign' (or there is no acceptable conversion)
error C2665: 'ostream_iterator<struct Man::Data,char,struct std::char_traits<char> >::ostream_iterator<struct Man::Data,char,struct std::char_traits<char> >' : none of the 2 overloads can convert parameter 1 from t
ype 'class ostream_withassign'

Помогите исправить!!! Пожалуста!!!

ivank
24-05-2006, 10:52
farik
friend fstream& operator << (fstream& stream, const Data& d)
{

RussianMessage("\nИмя: ");
stream<<d.name.c_str();

RussianMessage("\nФамилия: ");
stream<<d.surname.c_str();

RussianMessage("\nВозраст: ");
stream<<d.age;
return stream;

}
Вот это должно быть дейтвительно френдом, а не членом класса как сейчас. Плюс, будет лучше если оно будет принимать ostream, а не fstream. Аналогично для operator >>

upd И ещё будет неплохо, если оно не будет ничего писать на экран. Ибо при чтении из файла вылезут три сообщения непонятно к чему.

farik
24-05-2006, 20:42
Вот исправленная программа в ней всеравно ошибка :
error C2679: binary '<<' : no operator defined which takes a right-hand operand of type 'class std::istream_iterator<struct Data,char,struct std::char_traits<char> >' (or there is no acceptable conversion)

Вот программа:

#include <iostream>
#include <algorithm>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <functional>

using namespace std;

#include "windows.h"

void RussianMessage(char *message){
char rmessage[256];
CharToOem(message,rmessage);
cout<<rmessage;
}

int RussianMenu(){
RussianMessage("\nВведите 1 для добавления новой структуры в файл\n");
RussianMessage("Введите 2 для показа всех структур из файла\n");
RussianMessage("Введите 3 для поиска\n");
RussianMessage("Введите 4 для выхода\n");
int choice;
cin>>choice;
return choice;
}

struct Data {
Data() : age(0) {}
// переменная для возраста
int age;
// переменная для имени
std::string name;
// переменная для фамилии
std::string surname;



friend ofstream& operator << (ofstream&, const Data&);
friend ostream& operator << (ostream&, const Data&);
friend ofstream& operator >> (istream&, Data&);


};

ostream& operator << (ostream& stream, const Data& d)
{

RussianMessage("\nИмя: ");
stream<<d.name.c_str();

RussianMessage("\nФамилия: ");
stream<<d.surname.c_str();

RussianMessage("\nВозраст: ");
stream<<d.age;
return stream;

}

ofstream& operator << (ofstream& stream, const Data& d)
{
// Записываем возраст
stream<<d.age<<' ';
// Записываем имя
stream<<d.name.c_str()<<' ';
// Записываем фамилию
stream<<d.surname.c_str()<<' ';
return stream;

}

ofstream& operator >> (istream& stream, Data& d)
{
stream>>d.age;
stream>>d.name;
stream>>d.surname;

// return stream;
}

struct Pred:binary_function<Data,std::string, bool> {

Pred(){}

bool operator () (const Data& d, std::string str) const
{
return ( d.surname == str)? true : false;

}
};

class Man{
Data data_;

public:
// конструктор с параметрами
Man(char *n,char *s,int a);
// конструктор
Man();
// функция ввода данных
void Put();
// функция показа данных
void Show();
// функция сохранения в файл
void SaveToFile();
// функция показа содержимого файла
void ShowFromFile();
void SearchFile();

};
// конструктор
Man::Man(){}

// конструктор с параметрами
Man::Man(char *n,char *s,int a){
data_.name.assign(n);
data_.surname.assign(s);
data_.age = a;
}



// функция ввода данных
void Man::Put(){
std::string temp;
RussianMessage("\nВведите имя:\n");
cin>>temp;

data_.name.assign(temp);


RussianMessage("\nВведите фамилию:\n");
cin>>temp;

data_.surname.assign(temp);

RussianMessage("\nВведите возраст\n");
cin>>data_.age;
}

// функция показа данных
void Man::Show(){
RussianMessage("\nИмя:\n");
cout<<data_.name;
RussianMessage("\nФамилия:\n");
cout<<data_.surname;
RussianMessage("\nВозраст:\n");
cout<<data_.age<<"\n";
}
// функция сохранения в файл
void Man::SaveToFile(){

ofstream file("c:\\men.txt",ios::out|ios::app);
if(!file){
RussianMessage("Файл не открылся для чтения !!!");
exit(1);
}

// file<<data_;
}
//****************************poisk***********************************************************
void Man::SearchFile()
{
std::string surname;

fstream file("C://men.txt",ios::in);
if(!file){
RussianMessage("Файл не открылся для чтения !!!");
exit(1);
}

istream_iterator<Data> first(file), last , pos;

RussianMessage("Введите фамилию:");
cin>>surname;

pos = std::find_if(first,last,bind2nd(Pred(),surname));

if(pos == last)
RussianMessage("\nТакого сотрудника нет!\n");
else
cout<<pos;


}
// **************************************************************************************************** ***************
// функция показа содержимого файла
void Man::ShowFromFile(){
fstream file("C://men.txt",ios::in);
if(!file){
RussianMessage("Файл не открылся для чтения !!!");
exit(1);
}

istream_iterator<Data> first(file), last;

copy(first,last, ostream_iterator<Data>(cout,"\n"));

}
int main(){

Man a;
do{
switch(RussianMenu()){

case 1: // Добавление записи
a.Put();
a.SaveToFile();
break;
case 2: // Показ всех записей
a.ShowFromFile();
break;
case 3:
a.SearchFile();
break;
case 4:// Прощание с пользователем
RussianMessage("До Свидания\n");
return 0;
default: // Неправильный ввод
RussianMessage("Неверный Ввод\n");
}

}while(1);


}


Помогите пожалуста!!!

ivank
24-05-2006, 21:34
В целом код кривой и некрасивый. SaveToFile, ShowToFile и SearchFile должны быть статиками, как минимум. Соответственно структура Data должна быть переименована в Man, статическими функциями которой будут три названных выше. Так будет несколько красивше. Либо можно завести класс FileOfMen (или MenStorage :)), которому в конструкторе передавть имя файла; тогда будет оправдано использование функций-членов класса.

А ошибка возникает, потому что итератор pos вы не разименовываете. Т.е. строчка cout << pos, д.б. заменена на cout << *pos.

upd Ещё подумалось, раз Data - структура, то operator << и operator >> могут быть и не френдами - незачем, раз все поля открыты.

farik
24-05-2006, 22:25
Все исправил! Компилируется!!! Но не записывает в файл :o
Вот код,гляньте:

#include <iostream>
#include <algorithm>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <functional>

using namespace std;

#include "windows.h"

void RussianMessage(char *message){
char rmessage[256];
CharToOem(message,rmessage);
cout<<rmessage;
}

int RussianMenu(){
RussianMessage("\nВведите 1 для добавления новой структуры в файл\n");
RussianMessage("Введите 2 для показа всех структур из файла\n");
RussianMessage("Введите 3 для поиска по фамилиии\n");
RussianMessage("Введите 4 для поиска по имени\n");
RussianMessage("Введите 5 для выхода\n");
int choice;
cin>>choice;
return choice;
}

struct Data {
Data() : age(0) {}
// переменная для возраста
int age;
// переменная для имени
std::string name;
// переменная для фамилии
std::string surname;



//ofstream& operator << (ofstream&, const Data&);
// ostream& operator << (ostream&, const Data&);
//istream& operator >> (istream&, Data&);

};

ostream& operator << (ostream& stream, const Data& d)
{

RussianMessage("\nИмя: ");
stream<<d.name.c_str();

RussianMessage("\nФамилия: ");
stream<<d.surname.c_str();

RussianMessage("\nВозраст: ");
stream<<d.age;
return stream;

}

ofstream& operator << (ofstream& stream, const Data& d)
{
// Записываем возраст
stream<<d.age<<' ';
// Записываем имя
stream<<d.name.c_str()<<' ';
// Записываем фамилию
stream<<d.surname.c_str()<<' ';
return stream;

}

istream& operator >> (istream& stream, Data& d)
{
stream>>d.age;
stream>>d.name;
stream>>d.surname;

return stream;
}


struct Pred:binary_function<Data,std::string, bool> {

Pred(){}

bool operator () (const Data& d, std::string str) const
{
return ( d.surname == str)? true : false;

}
};

class Man{
Data data_;

public:
// конструктор с параметрами
Man(char *n,char *s,int a);
// конструктор
Man();
// функция ввода данных
void Put();
// функция показа данных
void Show();
// функция сохранения в файл
void SaveToFile();
// функция показа содержимого файла
void ShowFromFile();
void SearchFileN();
void SearchFileF();
};
// конструктор
Man::Man(){}

// конструктор с параметрами
Man::Man(char *n,char *s,int a){
data_.name.assign(n);
data_.surname.assign(s);
data_.age = a;
}



// функция ввода данных
void Man::Put(){
std::string temp;
RussianMessage("\nВведите имя:\n");
cin>>temp;

data_.name.assign(temp);


RussianMessage("\nВведите фамилию:\n");
cin>>temp;

data_.surname.assign(temp);

RussianMessage("\nВведите возраст\n");
cin>>data_.age;
}

// функция показа данных
void Man::Show(){
RussianMessage("\nИмя:\n");
cout<<data_.name;
RussianMessage("\nФамилия:\n");
cout<<data_.surname;
RussianMessage("\nВозраст:\n");
cout<<data_.age<<"\n";
}
// функция сохранения в файл
void Man::SaveToFile(){

ofstream file("c:\\men.txt",ios::out|ios::app);
if(!file){
RussianMessage("Файл не открылся для чтения !!!");
exit(1);
}

// file<<data_;
}
//****************************poisk po familii***********************************************************
void Man::SearchFileF()
{
std::string surname;

fstream file("C://men.txt",ios::in);
if(!file)
{
RussianMessage("Файл не открылся для чтения !!!");
exit(1);
}

istream_iterator<Data> first(file), last , pos;

RussianMessage("Введите фамилию:");
cin>>surname;

pos = std::find_if(first,last,bind2nd(Pred(),surname));

if(pos == last)
RussianMessage("\nТакого сотрудника нет!\n");
else
cout<<*pos;


}

// **************************************************************************************************** ***************
//***********************poisk po imeni*********************************************************************************
void Man::SearchFileN()
{
std::string name;

fstream file("C://men.txt",ios::in);
if(!file)
{
RussianMessage("Файл не открылся для чтения !!!");
exit(1);
}

istream_iterator<Data> first(file), last , pos;

RussianMessage("Введите имя:");
cin>>name;

pos = std::find_if(first,last,bind2nd(Pred(),name));

if(pos == last)
RussianMessage("\nТакого сотрудника нет!\n");
else
cout<<*pos;


}
//**************************************************************************************************** *********************
// функция показа содержимого файла
void Man::ShowFromFile(){
fstream file("C://men.txt",ios::out);
if(!file){
RussianMessage("Файл не открылся для чтения !!!");
exit(1);
}

istream_iterator<Data> first(file), last;

copy(first,last, ostream_iterator<Data>(cout,"\n"));

}
int main(){

Man a;
do{
switch(RussianMenu()){

case 1: // Добавление записи
a.Put();
a.SaveToFile();
break;
case 2: // Показ всех записей
a.ShowFromFile();
break;
case 3:
a.SearchFileF();
break;
case 4:
a.SearchFileN();
break;
case 5:// Прощание с пользователем
RussianMessage("До Свидания\n");
return 0;
default: // Неправильный ввод
RussianMessage("Неверный Ввод\n");
}

}while(1);


}

ivank
24-05-2006, 22:52
Отформатируйте код нормально. Мне надоело каждый раз когда я его читаю через indent прогонять :) Попробуйте всё заново переписать не смотря на старый код (но учитывая его ошибки), ибо то, что есть сейчас просто ужасно со всех точек зрения.

По вопросу: внимательно посмотрите на код SaveToFile, лишних комментариев не заместно?

Ещё у вас по имени искать не будет, посмотрите на предикат.

farik
25-05-2006, 00:39
что такое предикат

ivank
25-05-2006, 01:00
Предикат это третий параметр функции find_if. Понятие пришло из матлогики. В вашем случае это структура с говорящим названием Pred.

Делаем вывод, что код вы таки писали не сами. Ибо люди, которые знают, что такое istream_iterator и find_if, как минимум форматируют исходники лучше. Скорее из чужого слепили, причём разбираться не стали почему и что написано, а сразу спросили на форуме. Судя по предыдущим темам, вы вообще напрягаться не любите.




© OSzone.net 2001-2012