Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   файлы (http://forum.oszone.net/showthread.php?t=66131)

farik 24-05-2006 06:49 441654

файлы
 
Есть программа:
Код:

#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 441752

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 442010

Вот исправленная программа в ней всеравно ошибка :
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 442040

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

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

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

farik 24-05-2006 22:25 442061

Все исправил! Компилируется!!! Но не записывает в файл :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 442073

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

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

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

farik 25-05-2006 00:39 442096

что такое предикат

ivank 25-05-2006 01:00 442104

Предикат это третий параметр функции find_if. Понятие пришло из матлогики. В вашем случае это структура с говорящим названием Pred.

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


Время: 19:08.

Время: 19:08.
© OSzone.net 2001-