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

Поток как статическая компонента объкта - C++

Восстановить пароль Регистрация
 
 
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
02.08.2013, 20:17     Поток как статическая компонента объкта #1
Доброго вечера ! Выполняю упражнения по книге. Если вкратце то при компиляции возникает ошибка в результате добавления static fstream file в поле данных класса как того и требует упражнение (создать поток как стат компоненту объекта и создать 2 стат функции для управления). Может я что то неверно понял, подскажите пожалуйста, полная версия упражнения написана ниже.
C++
1
2
3
4
5
6
7
8
9
10
11
12
class employee
{
private:
 -||-
static fstream file;
public:
static void OpenFile()
{
   file.open("ex7.txt")
}
-||-
};
Упражнение: Другим подходом к добавлению файлового потока к объекту является превращение самого этого потока в статическую компоненту объекта. Для чего это делается? Ну, часто бывает проще представить себе поток связанным с классом в целом, а не с отдельными его объектами. К тому же, гораздо правильнее открывать поток только один раз для записи и чтения всего, что нужно. Например, мы открываем файл и начинаем последовательное чтение. Функция чтения всякий раз возвращает данные для следующего объекта. Указатель файла сдвигается при этом автоматически, так как между чтениями файл мы не закрываем.
Перепишите программы из упражнений 4 и 6 таким образом, чтобы использовать объект fstream в качестве статической компоненты класса name. Функционирование программы должно сохраниться. Напишите статическую функцию для открытия потока и еще одну — для сбрасывания файлового указателя и установки его на начало файла. Эту же функцию можно использовать для чтения всего файла.

Добавлено через 5 минут
Прошу прощения забыл инициализировать статическую компоненту после определения класса. Вопрос закрыт )
C++
1
2
3
4
5
6
7
class employee
{
private:
static fstream file;
..........
};
fstream employee::file;
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
02.08.2013, 20:21     Поток как статическая компонента объкта #2
неплохо бы ошибки еще сюда постить.
статические мемберы нужно явно инициализировать например. вы это сделали?
Kins
 Аватар для Kins
59 / 58 / 6
Регистрация: 03.02.2013
Сообщений: 167
02.08.2013, 20:29     Поток как статическая компонента объкта #3
в конструкторе открытие файла сделай, один раз и все. Это, если не ошибаюсь из Лафоре.
Valentina
66 / 66 / 3
Регистрация: 13.05.2012
Сообщений: 130
02.08.2013, 20:35     Поток как статическая компонента объкта #4
Цитата Сообщение от Kins Посмотреть сообщение
в конструкторе открытие файла сделай, один раз и все. Это, если не ошибаюсь из Лафоре.
а у Вас нету случайно примера решения данной задачи?
Kins
 Аватар для Kins
59 / 58 / 6
Регистрация: 03.02.2013
Сообщений: 167
02.08.2013, 20:42     Поток как статическая компонента объкта #5
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
#include "stdafx.h"
#include <fstream>
#include <iostream>
 
using namespace std;
 
const int MAX=80;
 
//////////////////////////////////////////////////////////////////////
class Name
{
private:
    char name[MAX];
    char fname[MAX];
    unsigned long number;
    static fstream file;
public:
    Name():number(0)
    {file.open("DATA.dat", ios::in|ios::out|ios::app|ios::binary);}
    Name(char nm, char fn, unsigned long n): name(), fname(), number(n)
    {}
    void getName()
    {
        cout <<"Введите имя: "; cin >>name;
        cout <<"Фамилию: "; cin >>fname;
        cout <<"Номер работника: "; cin >>number;
    }
    void showName()
    {
        cout <<"\nИмя: " <<name;
        cout <<"\nФамилия: " <<fname;
        cout <<"\nНомер работника: " <<number;
    }
    static void writeName(Name N)
    {
        //file.open("DATA.dat", ios::in|ios::app|ios::binary);
        if(!file)
        {cerr <<"Невозможно открыть файл!";}
        file.write(reinterpret_cast<char*>(&N), sizeof(N));
        if(!file)
        {cerr <<"Невозможно записать файл!";}
        //file.close();
    }
    static void readName(Name N)
    {
        //file.open("DATA.dat", ios::out|ios::binary);
        if(!file)
        {cerr <<"Невозможно открыть файл!";}
        file.seekg(0);
        file.read(reinterpret_cast<char*>(&N), sizeof(N));
        //if(!file)
        //{cerr <<"Невозможно прочесть файл!";}
        while(!file.eof()){
            N.showName();
            file.read(reinterpret_cast<char*>(&N), sizeof(N));
        }
        file.close();       
    }
};
fstream Name::file;
////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_ALL, "");
    Name N;
    char ch;
    do{
        N.getName();
        Name::writeName(N);
        cout <<"Еще раз (y/n)?";
        cin >>ch;
    }while(ch!='n');
    Name::readName(N);
    cout <<endl;
    system("pause");
    return 0;
}
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
02.08.2013, 23:35     Поток как статическая компонента объкта #6
статические поля класса должны быть объявлены ещё и глобально.
В этом дело? Я угадал?
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
03.08.2013, 00:22  [ТС]     Поток как статическая компонента объкта #7
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
статические поля класса должны быть объявлены ещё и глобально.
В этом дело? Я угадал?
Да, в этом

Добавлено через 6 минут
Цитата Сообщение от Kins Посмотреть сообщение
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
#include "stdafx.h"
#include <fstream>
#include <iostream>
 
using namespace std;
 
const int MAX=80;
 
//////////////////////////////////////////////////////////////////////
class Name
{
private:
    char name[MAX];
    char fname[MAX];
    unsigned long number;
    static fstream file;
public:
    Name():number(0)
    {file.open("DATA.dat", ios::in|ios::out|ios::app|ios::binary);}
    Name(char nm, char fn, unsigned long n): name(), fname(), number(n)
    {}
    void getName()
    {
        cout <<"Введите имя: "; cin >>name;
        cout <<"Фамилию: "; cin >>fname;
        cout <<"Номер работника: "; cin >>number;
    }
    void showName()
    {
        cout <<"\nИмя: " <<name;
        cout <<"\nФамилия: " <<fname;
        cout <<"\nНомер работника: " <<number;
    }
    static void writeName(Name N)
    {
        //file.open("DATA.dat", ios::in|ios::app|ios::binary);
        if(!file)
        {cerr <<"Невозможно открыть файл!";}
        file.write(reinterpret_cast<char*>(&N), sizeof(N));
        if(!file)
        {cerr <<"Невозможно записать файл!";}
        //file.close();
    }
    static void readName(Name N)
    {
        //file.open("DATA.dat", ios::out|ios::binary);
        if(!file)
        {cerr <<"Невозможно открыть файл!";}
        file.seekg(0);
        file.read(reinterpret_cast<char*>(&N), sizeof(N));
        //if(!file)
        //{cerr <<"Невозможно прочесть файл!";}
        while(!file.eof()){
            N.showName();
            file.read(reinterpret_cast<char*>(&N), sizeof(N));
        }
        file.close();       
    }
};
fstream Name::file;
////////////////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_ALL, "");
    Name N;
    char ch;
    do{
        N.getName();
        Name::writeName(N);
        cout <<"Еще раз (y/n)?";
        cin >>ch;
    }while(ch!='n');
    Name::readName(N);
    cout <<endl;
    system("pause");
    return 0;
}
Я решил писать в форматированном виде и вот в чем проблема, если убрать из главной функции main строчки employee::FileClose(); employee::FileOpen(); при записи после данных будет добавляться n-е количество символов заменить пробовал на seekg(0) но не помогло та же беда
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <fstream> // для потоковых файловых функций
#include <iostream>
#include <istream>
#include <string>
#include <typeinfo> // для typeid()
using namespace std;
#include <process.h> // для exit()
 
const int MAX=10;
class employee
{
private:
    char name[MAX];
    char surname[MAX];
    char firstname[MAX];
    unsigned long numb; 
    static fstream file;
public:
     static void  FileOpen()
    {
        file.open("ex7.2.txt", ios::app| ios::in |ios::out);
    }
     static void  FileClose()
    {
        file.close();
    }
    static void FileReset()
    {
    }
    void getdata()
    {
        cout<<endl<<"Введите Имя ";    cin>>name;
        cout<<endl<<"Введите Фамилию ";  cin>>surname;
        cout<<endl<<"Введите Отчество ";     cin>>firstname;
        cout<<endl<<"Введите номер работника ";  cin>>numb;
    }
    void putdata()
    {
        cout<<endl<<"Имя "<<name;
        cout<<endl<<"Фамилия "<<surname;
        cout<<endl<<"Отчество "<<firstname;
        cout<<endl<<"Номер работника "<<numb;
 
    }
    void write()
    {
        if(!file)
        {
        cout << "\nНевозможно открыть ex6.txt";
        cout << "\nfile = " << file;
        cout << "\nКод ошибки = " << file.rdstate();
        cout << "\ngood() = " << file.good();
        cout << "\neof() = " << file.eof();
        cout << "\nfail() = " << file.fail();
        cout << "\nbad() = " << file.bad() << endl;
        }
        else
        cout << "\nФайл открыт без ошибок.";
        file<<numb<<' '<<name<<' '<<surname<<' '<<firstname<<' ';
    }
    void read()
    {
        char temp[101];
        char ch;
        if(!file)
        {
        cout << "\nНевозможно открыть ex6.txt";
        cout << "\nfile = " << file;
        cout << "\nКод ошибки = " << file.rdstate();
        cout << "\ngood() = " << file.good();
        cout << "\neof() = " << file.eof();
        cout << "\nfail() = " << file.fail();
        cout << "\nbad() = " << file.bad() << endl;
        }
        else
        cout << "\nФайл открыт без ошибок.";
        //--
        //cout<<infile.rdbuf();
        //--
        //infile.getline(temp,100);
        //cout<<temp
        //--
        /*
        while(!infile.eof())
        {
        infile>>ch;
        cout<<ch;
        }
        */
        //--
        cout<<endl;
        while(file)
        {
        file.get(ch);
        cout<<ch;
        }
    }
    void readSpec()
    {
        int com;
        cout<<endl<<"Введите номер искомого работника "; cin>>com;
        if(!file)
        {
        cout << "\nНевозможно открыть ex7.2.txt";
        cout << "\nfile = " << file;
        cout << "\nКод ошибки = " << file.rdstate();
        cout << "\ngood() = " << file.good();
        cout << "\neof() = " << file.eof();
        cout << "\nfail() = " << file.fail();
        cout << "\nbad() = " << file.bad() << endl;
        }
        else
        cout << "\nФайл открыт без ошибок.";
 
        while(file)
        {
            file>>numb>>name>>surname>>firstname;
            if(numb == com)
            {
            cout<<"Искомый номер найден";
            break;
            }
        }
        this->putdata();
    }
};
fstream employee::file;
 
void main()
{
   setlocale( LC_ALL,"Russian" );
   employee pers;
   employee::FileOpen();
 
   char answ;
   cout<<endl;
   cout<<"Хотите добавить нового работника ? ";
   cin>>answ;
   while(answ=='y')
   {
   pers.getdata();
   pers.write();
   cout<<"Хотите продолжыть добавление ? ";
   cin>>answ;
   }
   employee::FileClose();
   employee::FileOpen();
   pers.read();
//   pers.readSpec();
 
   cout<<endl;
   system("pause");
}
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.08.2013, 00:39     Поток как статическая компонента объкта #8
При переходе от записи к чтению, нужно буфер очистить (flush()), потом курсор в начало передвинуть.
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
03.08.2013, 00:46  [ТС]     Поток как статическая компонента объкта #9
Цитата Сообщение от alsav22 Посмотреть сообщение
При переходе от записи к чтению, нужно буфер очистить (flush()), потом курсор в начало передвинуть.
Что то не помогает

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
      static void  FileFlush()
    {
        file.flush();
        file.seekp(0);
        file.seekg(0);
    }
void main()
{
   setlocale( LC_ALL,"Russian" );
   employee pers;
   employee::FileOpen();
 
   char answ;
   cout<<endl;
   cout<<"Хотите добавить нового работника ? ";
   cin>>answ;
   while(answ=='y')
   {
   pers.getdata();
   pers.write();
   cout<<"Хотите продолжить добавление ? ";
   cin>>answ;
   }
   employee::FileFlush();
   pers.read();
//   employee::FileClose();
//   employee::FileOpen();
 
//   pers.readSpec();
 
   cout<<endl;
   system("pause");
}
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.08.2013, 00:53     Поток как статическая компонента объкта #10
У меня работает даже если просто: file.seekg(0);

Добавлено через 1 минуту
Цитата Сообщение от ArkTaS Посмотреть сообщение
при записи после данных будет добавляться n-е количество символов
Это где видите? В файле? При выводе из файла?

Добавлено через 1 минуту
Файл новый создаёте? Может у вас старый остался?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.08.2013, 00:59     Поток как статическая компонента объкта #11
При таком, например, варианте:
C++
1
2
3
4
5
6
static void FileFlush()
    {
        file.clear();
        file.flush();
        file.seekg(0);
    }
Миниатюры
Поток как статическая компонента объкта  
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
03.08.2013, 01:03  [ТС]     Поток как статическая компонента объкта #12
Цитата Сообщение от alsav22 Посмотреть сообщение
У меня работает даже если просто: file.seekg(0);

Добавлено через 1 минуту

Это где видите? В файле? При выводе из файла?

Добавлено через 1 минуту
Файл новый создаёте? Может у вас старый остался?
И в файле и при выводе. Да файл был старый. Удалил старый файл и этот глюк пропал.. Не пойму только как это помогло ?!
Сделал опыт удалил старый файл все заработало, потом убрал строку с переводом указателя на начало и очисткой буфера, появился глюк, потом вернул эту строку но глюк уже не проходит)) Напомню глюк состоит в том что после каждой новой записи добавляется n-е количество повторяющихся иероглифов или символов
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.08.2013, 01:06     Поток как статическая компонента объкта #13
Цитата Сообщение от ArkTaS Посмотреть сообщение
потом вернул эту строку но глюк уже не проходит))
И не пройдёт пока файл с неправильной записью не удалите.
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
03.08.2013, 01:10  [ТС]     Поток как статическая компонента объкта #14
Цитата Сообщение от alsav22 Посмотреть сообщение
И не пройдёт пока файл с неправильной записью не удалите.
А как это можно объяснить ?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.08.2013, 01:12     Поток как статическая компонента объкта #15
Цитата Сообщение от ArkTaS Посмотреть сообщение
А как это можно объяснить ?
Почему лишнее пишется в файл?
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
03.08.2013, 01:57  [ТС]     Поток как статическая компонента объкта #16
Цитата Сообщение от alsav22 Посмотреть сообщение
Почему лишнее пишется в файл?
Да, лишнее, эти левые, повторяющие символы при чем в количестве 300-500
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.08.2013, 02:16     Поток как статическая компонента объкта #17
Чтение/запись буферизованы, всё сначала в буфер, потом в файл. Если после записи не освобождать буфер (или при закрытии файла, или через flush()), то, при переходе к чтению, выведется содержимое буфера от позиции курсора (где он остановился при записи) и до конца буфера, а там муссор. Запись же в файл произойдёт (в данном коде) при окончании программы, и просто запишется всё содержимое буфера, и данные и муссор.
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
03.08.2013, 02:29  [ТС]     Поток как статическая компонента объкта #18
Цитата Сообщение от alsav22 Посмотреть сообщение
Чтение/запись буферизованы, всё сначала в буфер, потом в файл. Если после записи не освобождать буфер (или при закрытии файла, или через flush()), то, при переходе к чтению, выведется содержимое буфера от позиции курсора (где он остановился при записи) и до конца буфера, а там муссор. Запись же в файл произойдёт (в данном коде) при окончании программы, и просто запишется всё содержимое буфера, и данные и муссор.
Но ведь курсор записи один, а курсов чтения другой, на то для каждого свои функции seekp, tellp и seekg, seekg
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.08.2013, 02:37     Поток как статическая компонента объкта #19
У вас поток создан универсальный: для чтения/записи, поэтому для него будет работать и то, и то.

Добавлено через 4 минуты
Пример работы вашего кода, как раз и говорит о том, что всё у него общее.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.08.2013, 02:44     Поток как статическая компонента объкта
Еще ссылки по теме:

Скопировать поток и добавить ошибки в поток C++
Статический метод как точка входа в поток - как избавиться C++
Как очистить входной поток от '\n'? C++

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

Или воспользуйтесь поиском по форуму:
ArkTaS
1 / 1 / 0
Регистрация: 01.07.2013
Сообщений: 127
03.08.2013, 02:44  [ТС]     Поток как статическая компонента объкта #20
Цитата Сообщение от alsav22 Посмотреть сообщение
У вас поток создан универсальный: для чтения/записи, поэтому для него будет работать и то, и то.

Добавлено через 4 минуты
Пример работы вашего кода, как раз и говорит о том, что всё у него общее.
Вы имеете ввиду что когда установлено оба режима fstream file(" name", iso::in | ios::out | ios::app) то работает только 1 указатель ?
А как же бит ios:: app который ставит указатель записи всегда на конец файла. А читаем то мы всегда с 0.
Значит все же у потока имеются оба указателя даже при такой настройке. В чем я ошибаюсь ?!
Yandex
Объявления
03.08.2013, 02:44     Поток как статическая компонента объкта
Ответ Создать тему
Опции темы

Текущее время: 05:57. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru