Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.95/43: Рейтинг темы: голосов - 43, средняя оценка - 4.95
72 / 71 / 8
Регистрация: 04.08.2010
Сообщений: 434
1

Решить упражнение на файловый ввод/вывод из книги Лафоре (12 глава)

08.12.2010, 18:59. Показов 8200. Ответов 40
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток.
В очередной раз обращаюсь за советом касательно разъяснения задачи
Другим подходом к добавлению файлового потока к объекту является превращение самого этого потока в
статическую компоненту объекта. Для чего это делается? Ну, часто бывает проще представить себе поток связанным
с классом в целом, а не с отдельными его объектами. К тому же, гораздо правильнее открывать поток только один
раз для записи и чтения всего, что нужно. Например, мы открываем файл и начинаем последовательное чтение.
Функция чтения всякий раз возвращает данные для следующего объекта. Указатель файла сдвигается при этом
автоматически, так как между чтениями файл мы не закрываем.
Понимаю типы ifstream, ofstream как записать в файл класс, как считать. Но тут что делать вообще не понимаю.
Как полностью считать в
C++
1
static fstream file
весь файл, как из этого
C++
1
file
выдирать нужную запись\

Вот решенная задача которую нужно переделать\ (в ней вроде бы все просто)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include<iostream>
#include<fstream>
using namespace std;
class Persona
{
private:
    int number;
    char surname[15];
    char name[15];
    char surname2[15];
public:
    void bern()
    {
        ofstream file;
        file.open("Persona1204.dat",ios::binary|ios::app);
        file.write((char*)this,sizeof(*this));
        file.close();
    }
    void read(int a)
    {
        ifstream file;
        file.open("Persona1204.dat",ios::binary);
        file.seekg((a-1)*sizeof(Persona));
        file.read((char*)this,sizeof(*this));
        file.close();
    }
    static int count()
    {
        ifstream file;
        file.open("Persona1204.dat",ios::binary);
        file.seekg(0,ios::end);
        return (int)(file.tellg()/sizeof(Persona));
    }
    friend istream& operator>>(istream& s,Persona& p)
    {
        cout << "Введите номер: ";
        s >> p.number;
        cout << "Введите фамилию: ";
        s >> p.surname;
        cout << "Введите имя: ";
        s >> p.name;
        cout << "Введите отчество: ";
        s >> p.surname2;
        p.bern();
        return s;
    }
    friend ostream& operator<<(ostream& s,Persona& p)
    {
        int a;
        s << "Всего записей: " << p.count() << endl;
        s << "Какую вывести: ";
        cin >> a;
        p.read(a);
        s << p.number << "\t" << p.surname << "\t" << p.name << "\t" << p.surname2 << endl;
        return s;
    }
};
int main()
{
    setlocale(LC_ALL,"Russian");
    Persona p;
    //cin >> p;
    cout << p;
    return EXIT_SUCCESS;
}
Добавлено через 39 минут
И немного хотелось бы разьяснения понятия файловый поток с физической точки зрения.
Как я понимаю - это как бы "мост" между файлом и пользователем

Добавлено через 52 минуты
Товарищи Гуру. хотелось бы услышать хоть намек, куда смотреть)

Добавлено через 3 часа 41 минуту
Апну на правах важности темы)
1
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.12.2010, 18:59
Ответы с готовыми решениями:

Зацикливание программы. В чем же ошибка? ( Упражнение 5 Глава 7 Лафоре ООП C++)
Миллион раз пересмотрел, ну не вижу ошибку и все тут :(. Должна же остановка на вводе быть! Что...

Упражнение из книги Лафоре
//11.cpp #include &lt;iostream&gt; using namespace std; class sterling { private: long pounds;...

Упражнение №8 глава 5 из книги Страуструпа
Здравствуйте. Помогите решить задание. Напишите программу,считывающую ряд чисел и записывающую их...

Работа с Классами или разбираем 10 Упражнение 6 главы книги ООП в С++ Р.Лафоре
Доброго времени суток господа. Подскажите пожалуйста каким образом можно объединить классы? Почему...

40
1 / 7 / 3
Регистрация: 06.04.2011
Сообщений: 85
13.10.2011, 06:24 2
Похоже что тема мертва попробуем ее оживить! Я тоже сейчас читаю Лафора и не могу решить это задание, хотел уже создавать новую тему, но нашел эту через поиск.
0
Заблокирован
13.10.2011, 07:07 3
Если бы было задание: нужно написать такой то и такой то класс...

У вас же можно только эврестически догадываться о том, что требуется сделать.
Конкретизируйте задачу.

Вы создаете десять объектов. Потом каждый поочередно сохраняете на диске.

Теперь у вас есть файл данных для 10ти объектов.

Вы создаете объект - он автоматически берёт свои данные с диска (каретка данных в файле перемещается на следущую запись) поскольку файл не закрывается - данные о каретке сохраняются.

Теперь вы создаете 2й объект - и он как и первый инициализируется данными из файла по текущей каретке.

Получается, что вы можете сохранять состояния объектов.

А потому в другой момент времени заного создавать объекты, каждый из которых автоматически проинициализируется данными сохраненными в прошлый сеанс работы
0
1 / 7 / 3
Регистрация: 06.04.2011
Сообщений: 85
13.10.2011, 20:45 4
В общем меня только интересует как записывать и загружать данные с файла не закрывая его? Я пробовал записывать только поля и загружать данные тоже только в них потом делал вывод и загружал следующие данные с файла. Но из за того что я не закрывал файл вывод странно себя ведет или выводит 2 раза последнее поле или после одного вывода на экран снова повторить вывод не получается, файловый указатель вообще не понятно как себя ведет в такой ситуации, я сбрасываю его на 0 перед выводом но потом потом он становиться -1 и не хочет заново устанавливаться на 0.
0
Заблокирован
13.10.2011, 20:57 5
Цитата Сообщение от Sylvos Посмотреть сообщение
В общем меня только интересует как записывать и загружать данные с файла не закрывая его?
Например - просто тупо не закрывать файл:

C++
1
2
3
4
5
6
7
8
void read(int a)
        {
                ifstream file;
                file.open("Persona1204.dat",ios::binary);
                file.seekg((a-1)*sizeof(Persona));
                file.read((char*)this,sizeof(*this));
                file.close();
        }
Если сделать метод - членом класса, да не просто, а статиком, то объект file не будит каждый раз заново создаваться при каждом вызове метода. А будит создан лишь один раз, и все это время жить в области видимости функции.

Если ему не делать close() то он и закрываться не будит.
Он закроется автоматически в деструкторе при завершении работы всего приложения.

Таким образом, каждый вновь созданный объект запускает статик-метод, и заполняет себя данными. Внутри этого статитка живёт фстрим, который не уничтожается и не закрывается по завершении статик метода, и поэтому сохраняет актуальную позицию каретки
0
1 / 7 / 3
Регистрация: 06.04.2011
Сообщений: 85
13.10.2011, 21:50 6
У меня такой простой вариант, вывод все равно происходит один раз, второй раз снова вывести не получается данные, надо закрывать программу и снова потом надо ее запускать чтобы вывести данные из файла
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include<iostream>
using namespace std;
#include<fstream>
class Name
{
    char n[50],f[50],o[50];
    unsigned long num;
    static fstream file;
public:
    Name()
    {
        Open();
    }
    static void Open();
    void Save()
    {
        file<<n<<' '<<f<<' '<<o<<' '<<num<<' ';
    }
    void Load()
    {
        file.seekg(0);
        while(!file.eof())
        {
            file>>n>>f>>o>>num;
            if(file.eof())
            {
                break;
            }
            Cout();
            system("PAUSE");
        }
    }
    void Cout()
    {
        cout<<"Имя: "<<n<<endl
            <<"Фамилия: "<<f<<endl
            <<"Отчество: "<<o<<endl
            <<"Номер телефона: "<<num<<endl<<endl;
    }
    void Cin()
    {
        cout<<"Введите Имя: ";
        cin>>n;
        cout<<"Введите Фамилию: ";
        cin>>f;
        cout<<"Введите Отчество: ";
        cin>>o;
        cout<<"Введите Номер телефона: ";
        cin>>num;
    }
    void Menu()
    {
        char ch;
        do
        {
            cout<<"1. Ввод новой анкеты"<<endl
                <<"2. Вывести анкету на екран"<<endl
                <<"3. Запись анкеты в файл"<<endl
                <<"4. Вывести содержимое файла на экран"<<endl
                <<"5. Выход"<<endl;
            cin>>ch;
            switch(ch)
            {
                case'1':Cin();break;
                case'2':Cout();break;
                case'3':Save();break;
                case'4':Load();break;
                case'5':break;
                default:cout<<"Не правильный ввод даных повторите попытку"<<endl;system("PAUSE");
            }
        }
        while(ch!='5');
    }
};
fstream Name::file;
void Name::Open()
{
    file.open("D:\\Data.txt",ios::in|ios::out|ios::binary|ios::app);
}
int main()
{
    setlocale(LC_ALL,"Rus");
    Name n;
    n.Menu();
    return 0;
}
Добавлено через 32 минуты
Help please
0
Заблокирован
13.10.2011, 21:52 7
Sylvos мне вам хочется сразу сказать одну вещь: Ваш код плохо читается.
Вы запихали в класс все - все методы, и реализации.

Сделайте в объявлении класса только прототипы, и комментарии объясняющие что эти прототипы должны делать. А реализацию ниже.

Тогда уже можно будит нормально посмотреть, подумать, что там не так.
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
13.10.2011, 22:30 8
Sylvos, напиши что ты вводишь (если вводишь) с консоли что видишь и что хочешь увидеть
0
1 / 7 / 3
Регистрация: 06.04.2011
Сообщений: 85
13.10.2011, 22:39 9
Решить упражнение на файловый ввод/вывод из книги Лафоре (12 глава)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include<iostream>          //Поключаем библиотеку iostream
using namespace std;        //Чтобы не писать std:: перед каждим cin или cout
#include<fstream>           //Поключаем библиотеку fstream
class Name                  //Клаас Name
{
private:                    //Закрытые поля класся
    char n[50],f[50],o[50]; //Имя, Фамилия, Отчество
    unsigned long num;      //Номер телефона
    static fstream file;    //Статический Указатель на Файл
public:                     //Открытые методы класса
    Name();                 //Конструктор по умолчанию
    void Open();            //Создаеть файл
    void Save();            //Сохранить поля класса в файл
    void Load();            //Загружает данные из файла в поля класса и выводит их на екран, делате так пока не дойдет до конца файла
    void Cout();            //Вывод на екран полей класса
    void Cin();             //Ввод даныхв поля класса
    void Menu();            //Меню выбора
};
//-----------------------------------------------------------------------------------
fstream Name::file;
//-----------------------------------------------------------------------------------
Name::Name()                //Конструктор по умолчанию
{
    Open();                 //Запустить метод Oen(); который Создаеть файл
}
//-----------------------------------------------------------------------------------
void Name::Open()           //Создаеть файл
{
    file.open("D:\\Data.txt",ios::in|ios::out|ios::binary|ios::app);
    //Создать файл Data.txt на диске D:\ с возможностью записи, чтени, в бинарном режиме, записывать даные в конец файла
}
//-----------------------------------------------------------------------------------
void Name::Save()           //Сохранить поля класса в файл
{
    file.seekp(0,ios::end);     //Перевести указатель файла в конец файла
    file<<n<<' '<<f<<' '<<o<<' '<<num<<' '; //сохрание данных в файл
}
//-----------------------------------------------------------------------------------
void Name::Load()           //Загружает данные из файла в поля класса и выводит их на екран, делате так пока не дойдет до конца файла
{
    file.seekp(0,ios::beg);     //Перевести указатель файла на начало файла     
    while(!file.eof())          //До тех пор пока не дойдет до конца файла
    {
        file>>n>>f>>o>>num;     //Читать даные из файла и записывать их в поля
        if(file.eof())          //Если конец файла выйти из цикла не вводить конец файла на екран
            break;          
        Cout();                 //Вывести на екран поля класса
    }
}
//-----------------------------------------------------------------------------------
void Name::Cout()           //Вывод на екран полей класса
{
    cout<<"Имя: "<<n<<endl                       //Выводит текст Имя: и поле класса n
        <<"Фамилия: "<<f<<endl                   //Выводит текст Фамилия: и поле класса f
        <<"Отчество: "<<o<<endl                 //Выводит текст Отчество: и поле класса o
        <<"Номер телефона: "<<num<<endl<<endl; //Выводит текст Номер телефона: и поле класса num
}
//-----------------------------------------------------------------------------------
void Name::Cin()            //Ввод даныхв поля класса
{
    cout<<"Введите Имя: ";        //Выводит текст Введите Имя:
    cin>>n;                     //Ввод имени в поле n
    cout<<"Введите Фамилию: ";    //Выводит текст Введите Фамилия:
    cin>>f;                     //Ввод фамили в поле f
    cout<<"Введите Отчество: ";  //Выводит текст Введите Отчество:
    cin>>o;                     //Ввод отчества в поле o
    cout<<"Введите Номер телефона: ";//Выводит текст Введите Номер телефона:
    cin>>num;                   //Ввод телефона в поле num
}
//-----------------------------------------------------------------------------------
void Name::Menu()           //Меню выбора
{
    char ch;                //Перемменная через которую пользователь производит ввод
    do                      //Запуск цикла
    {
        cout<<endl;
        cout<<"1. Ввод новой анкеты"<<endl                   //Ну тут думаю итка все понятно
            <<"2. Вывести анкету на екран"<<endl            //
            <<"3. Запись анкеты в файл"<<endl              //
            <<"4. Вывести содержимое файла на экран"<<endl //
            <<"5. Выход"<<endl<<endl;
        cin>>ch;            //Ввод пользователя
        cout<<endl;
        switch(ch)          //Анализ ввода пользователя
        {
            case'1':Cin();break;    
            case'2':Cout();break;
            case'3':Save();break;
            case'4':Load();break;
            case'5':break;
            default:cout<<"Не правильный ввод даных повторите попытку"<<endl;system("PAUSE");
        }
    }
    while(ch!='5');//Условие цикла Пока пользователь не введет 5
}
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
int main()
{
    setlocale(LC_ALL,"Rus");
    Name n;
    n.Menu();
    return 0;
}
0
23 / 23 / 4
Регистрация: 05.11.2010
Сообщений: 134
13.10.2011, 22:43 10
Простите. Опоздали
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
13.10.2011, 22:44 11
А чё такое OMG и WTF?

Не по теме:

Сёдня не гляну, завтра гляну, щас спать

0
1 / 7 / 3
Регистрация: 06.04.2011
Сообщений: 85
13.10.2011, 23:03 12
Цитата Сообщение от kravam Посмотреть сообщение
А чё такое OMG и WTF?

Не по теме:

Сёдня не гляну, завтра гляну, щас спать

Не по теме:

OMG — аббревиатура Oh My God! (рус. О, Боже мой!) — общеупотребительное сокращение-англицизм при текстовом общении.
WTF — аббревиатура в Интернет-сленге, означающая «what the fuck?» (англ. «какого хрена?», «что за херня?»)

0
Заблокирован
13.10.2011, 23:14 13
Sylvos, слишком много коментариев тоже не нужно))
комментарии должны пояснять что делает данный метод (либо данный алгоритм)
Не нужно комментировать одно и тоже дважды, и не нужно комментировать совсем очивидные вещи. Любому программисту с++ будит понятно что Name(); это конструктор

Теперь второй момент: у вас есть класс, который называется Name. То есть, это класс имен.
Какую задачу выполняет класс имен?
Судя по коду - создание анкет, и управление этими анкетами. Допустим - отобразить все анкеты в консоли.

Вам не кажется, что имя класса Name не отражает сути той задачи, которую решает класс? Назовите тогда его уже CManagerListPerson - менеджер анкет

И тогда вы сразу заметите, что сама по себе логика вашего менеджера и задача заявленная по сабжу - совершенно в разных плоскостях существуют.

То есть ваш класс решает совсем не ту задачу, которую задал преподаватель.
Задача по сабжу - создать такой класс, объекты которого могли бы анициализировать себя данными автоматически, подкачивая их с диска.

Там не было задачи, что бы эти объекты при этом являлись менеджерами этой самой базы данных, откуда они будут брать данные

(или я сам в корне не верно истолковал сабж)
0
23 / 23 / 4
Регистрация: 05.11.2010
Сообщений: 134
13.10.2011, 23:20 14
Сделайте ещё контроль ввода данных!
А то если номер телефона вводишь не цифры, а буквы, то код просто поднимет бурю строк с ошибками.
Например:
C++
1
2
3
4
5
6
 int input;
 
         cout << "Введите число" << endl;
         cin >> input;
         if(!cin.fail())
          cout << "Введено целое число: " << input << endl
Грубо скажу
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{......
                        case'1':Cin();break;    
                        case'2':Cout();break;
                        case'3':Save();break;
          int input;
 
         cout << "Введите число" << endl;
         cin >> input;
         if(!cin.fail())
          cout << "Введено целое число: " << input << endl
 
 
                        case'4':Load();break;
                        case'5':break;
                        default:cout<<"Не правильный ввод даных повторите попытку"<<endl;system("PAUSE");
 .....             
  }
Если будет стоять контроль ввода данных, то будет срабатывать:
Не правильный ввод даных повторите попытку
Я может где и ошибаюсь, так как я новичок. Но надеюсь что думаю верно.
0
1 / 7 / 3
Регистрация: 06.04.2011
Сообщений: 85
13.10.2011, 23:33 15
Ребята это не экзаменационное задание! Это упражнения для самопроверки из 12 главы "Потоки и файлы" книги "Объектно-ориентированное программирование в C++." 4 издание автора Лафоре Р. Я стараюсь делать все задания из этой книги но уже 2 +1 пропустил. Наверно я сам не правильно понял что нужно сделать в задание. Зачем нужен статический указатель на файл в классе? И почему файл который создается в бинарном режиме можно открыть обычным блокнотом я думал что там должно быть что то типа машинyого кода "‰Ў‡ЄЄъ8¶H" И как правильно записывать и читать данные с него ?
0
23 / 23 / 4
Регистрация: 05.11.2010
Сообщений: 134
13.10.2011, 23:41 16
У меня пока что нет такой практики, чтобы ответить на все вопросы. Главное - нужно понять алгоритм действий, а остальное придёт с опытом. Я тоже новичок и тоже читаю ту же книгу. Правда пока что тяжело сообразить что с нуля, но стараюсь определять в кодах ошибки. Москва не сразу строилась
0
Заблокирован
14.10.2011, 00:07 17
Цитата Сообщение от Sylvos Посмотреть сообщение
Зачем нужен статический указатель на файл в классе?
Тут нужно понять идею! Смотрите:

Представьте себе карету, которую везут упряжка из трех лошадок.
Каждая лошадка - это экземпляр класса.
Каждая лошадка может иметь свой цвет, возраст, и скорость передвижения.

Но поскольку все лошадки в одной упряжке, то параметр "скорость" у них у всех одинаковый.
Получается, что нет никакого смысла каждой лошадке помнить одно и тоже число.
Нет смысла каждой лошадке помнить свою скорость.


Ну так вот, статический элемент данных класса - это и есть поле, общее для всех объектов данного класса.

То есть, возвраст и цвет у каждой лошадке свой уникальный. А скорость у всех - общая. Одинаковая.

Всегда, когда вам захочется сделать для всех объектов класса какое то поле общим - вы делаете его статиком

Добавлено через 7 минут
Цитата Сообщение от Sylvos Посмотреть сообщение
И почему файл который создается в бинарном режиме можно открыть обычным блокнотом я думал что там должно быть что то типа машинyого кода "‰Ў‡ЄЄъ8¶H"
Бинарный режим - это просто последовательность байтов. И ничего более.

Можно записать в файл символы и строки, и читать так же.
А можно записывать в файл последовательности байтов, и читать так же.

Структура в памяти компьютера - это просто некоторая область памяти, которая имеет определенный размер.

Вместо того, что бы записывать в файл строки и символы, можно открыть файл в бинарном режиме, и сразу закинуть туда всю структуру целиком - все что имелось в данный момент по адресу начала структуры окажется в файле
2
448 / 211 / 21
Регистрация: 07.10.2011
Сообщений: 462
14.10.2011, 00:07 18
Лучший ответ Сообщение было отмечено как решение

Решение

Добавь в функцию Load() первой строкой строку
file.clear();

Дело в том, что после первой попытки вывода ты достиг конца файла и соответствующий флаг установился в 1. Поэтому все последующие проверки while(!file.eof()) не проходили, следовательно. из файла просто ничего не читалось, потому что флажок eof говорил твоему потоку, что конец файла уже достигнут.

Метод clear() чистит эти флажки, поэтому теперь повторный вывод из файла будет возможен
3
Заблокирован
14.10.2011, 00:14 19
Цитата Сообщение от LineStown Посмотреть сообщение
И немного хотелось бы разьяснения понятия файловый поток с физической точки зрения.
Как я понимаю - это как бы "мост" между файлом и пользователем
Да. Вы правильно понимаете.

Главное понять: файловый поток - это средство доставки данных от пользователя к самому файлу.

А файл - это не обязательно текстовый документ, это может быть что угодно, что умеет получать/отправлять данные. Например, принтер, или даже окошко виндовс.
1
kazak
14.10.2011, 00:16     Решить упражнение на файловый ввод/вывод из книги Лафоре (12 глава)
  #20

Не по теме:

aeshes, ну хоть кто-то догадался:)

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.10.2011, 00:16

Упражнение по программированию (Стивен Прата, глава 2, упражнение 3)
2 Глава, вопрос 3. Напишите программу на С++, которая использует три определяемых пользователем...

Упражнение из Лафоре. Тема Перечисления. Как правильно сделать вывод?
Условие: в программе определен печесляемый тип данных etype, отражающий должность сотрудника enum...

Решить задачу на файловый ввод/вывод (игра "Города")
Не могу понять задачу и решить её на Си!!! Срочно! Дело в том что я сейчас на зачёте, и мне...

Заменить в программе, переводящую строку в двоичный код, консольный ввод/вывод на файловый ввод/вывод
Добрый день! Помогите, пожалуйста, с программой. Программа считывает строку с клавиатуры и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru