Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 51, средняя оценка - 4.98
LineStown
66 / 66 / 3
Регистрация: 04.08.2010
Сообщений: 420
Завершенные тесты: 1
#1

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

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

Доброго времени суток.
В очередной раз обращаюсь за советом касательно разъяснения задачи
Другим подходом к добавлению файлового потока к объекту является превращение самого этого потока в
статическую компоненту объекта. Для чего это делается? Ну, часто бывает проще представить себе поток связанным
с классом в целом, а не с отдельными его объектами. К тому же, гораздо правильнее открывать поток только один
раз для записи и чтения всего, что нужно. Например, мы открываем файл и начинаем последовательное чтение.
Функция чтения всякий раз возвращает данные для следующего объекта. Указатель файла сдвигается при этом
автоматически, так как между чтениями файл мы не закрываем.
Понимаю типы 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)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.12.2010, 18:59
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Решить упражнение на файловый ввод/вывод из книги Лафоре (12 глава) (C++):

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

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

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

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

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

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

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

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

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

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

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

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

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

А потому в другой момент времени заного создавать объекты, каждый из которых автоматически проинициализируется данными сохраненными в прошлый сеанс работы
0
Sylvos
-25 / 6 / 1
Регистрация: 06.04.2011
Сообщений: 85
13.10.2011, 20:45 #4
В общем меня только интересует как записывать и загружать данные с файла не закрывая его? Я пробовал записывать только поля и загружать данные тоже только в них потом делал вывод и загружал следующие данные с файла. Но из за того что я не закрывал файл вывод странно себя ведет или выводит 2 раза последнее поле или после одного вывода на экран снова повторить вывод не получается, файловый указатель вообще не понятно как себя ведет в такой ситуации, я сбрасываю его на 0 перед выводом но потом потом он становиться -1 и не хочет заново устанавливаться на 0.
0
Bers
Заблокирован
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
Sylvos
-25 / 6 / 1
Регистрация: 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
Bers
Заблокирован
13.10.2011, 21:52 #7
Sylvos мне вам хочется сразу сказать одну вещь: Ваш код плохо читается.
Вы запихали в класс все - все методы, и реализации.

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

Тогда уже можно будит нормально посмотреть, подумать, что там не так.
0
kravam
быдлокодер
1695 / 882 / 45
Регистрация: 04.06.2008
Сообщений: 5,459
13.10.2011, 22:30 #8
Sylvos, напиши что ты вводишь (если вводишь) с консоли что видишь и что хочешь увидеть
0
Sylvos
-25 / 6 / 1
Регистрация: 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
Revol'veR
23 / 23 / 2
Регистрация: 05.11.2010
Сообщений: 134
13.10.2011, 22:43 #10
Простите. Опоздали
0
kravam
быдлокодер
1695 / 882 / 45
Регистрация: 04.06.2008
Сообщений: 5,459
13.10.2011, 22:44 #11
А чё такое OMG и WTF?

Не по теме:

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

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

Не по теме:

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

Не по теме:

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

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

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

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

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

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

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

(или я сам в корне не верно истолковал сабж)
0
Revol'veR
23 / 23 / 2
Регистрация: 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
Sylvos
-25 / 6 / 1
Регистрация: 06.04.2011
Сообщений: 85
13.10.2011, 23:33 #15
Ребята это не экзаменационное задание! Это упражнения для самопроверки из 12 главы "Потоки и файлы" книги "Объектно-ориентированное программирование в C++." 4 издание автора Лафоре Р. Я стараюсь делать все задания из этой книги но уже 2 +1 пропустил. Наверно я сам не правильно понял что нужно сделать в задание. Зачем нужен статический указатель на файл в классе? И почему файл который создается в бинарном режиме можно открыть обычным блокнотом я думал что там должно быть что то типа машинyого кода "‰Ў‡ЄЄъ8¶H" И как правильно записывать и читать данные с него ?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.10.2011, 23:33
Привет! Вот еще темы с ответами:

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

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

Лафоре. Глава 11. Задача 2 - C++
Решал задачку из учебника - Лафоре. Глава 11. Задача 2. Вот код #include &lt;iostream&gt; #include &lt;iomanip&gt; #include &lt;conio.h&gt; ...

Правильное ли решение задачи? Лафоре. 3 глава 9 задача - C++
Представьте, что вы собираетесь пригласить к себе шестерых гостей, но за вашим столом могут разместиться всего лишь 4 человека Сколькими...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
13.10.2011, 23:33
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru