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

Потоковый ввод из файла вместе с классом. Не пойму в чем причина - C++

Восстановить пароль Регистрация
 
Nozi
0 / 0 / 0
Регистрация: 31.01.2014
Сообщений: 5
31.01.2014, 13:44     Потоковый ввод из файла вместе с классом. Не пойму в чем причина #1
Привет народ. У меня такая проблема. Пишу лабораторную, и не могу таким способом (показан ниже) ввести всю таблицу и сохранить внутри программы. В этой лабораторной изучается раздел Классы, но видимо причина не в этом.
До этого делал лабораторную со структурой и такой же ввод с помощью while выводил мне все, что есть в файле, все данные сохранялись в поток, а оттуда в массив структур.

Вот пример ввода моей программы
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int read(char* file_name, Man planets[], char* pName,float diam,bool life, int sput, int l_name, int& kol_planet)
{   
    ifstream plan(file_name);
    
    while (plan)
    {
        
        plan>>pName;
            planets[kol_planet].name(l_name,pName,kol_planet);
        plan>>diam;
            planets[kol_planet].metr(diam);
        plan>>life;
            planets[kol_planet].sLife(life);
        plan>>sput;
            planets[kol_planet].snic(sput);
        kol_planet++;
        
    }
    
    cout<<endl<<"Прочитано!"<<endl;
    return kol_planet;
}
а вот, что лежит в файле:

Mercury 4878 false 0
Venus 12104 false 0
Earth 12774 true 1
Mars 6786 true 2
Jupiter 142796 false 16
Saturn 120000 false 17
Uranus 51108 false 5
Neptune 49600 false 2
Pluto 2280 false 1

так вот. считывается только первая строка, а при новом заходе в цикл, он якобы не выполняется и соскакивает.

Если что:

C++
1
Man *planets=new Man(pName,diam,life,sput,l_name);
и
C++
1
char *file_name = "planeta.txt";
Пробовал .eof(), и через getline, а ведь в предыдущей лабе мой способ работал.
Помогите разобраться
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.01.2014, 13:44     Потоковый ввод из файла вместе с классом. Не пойму в чем причина
Посмотрите здесь:

C++ потоковый ввод
потоковый ввод - вывод C++
C++ Потоковый ввод-вывод
Как перенести приложение вместе с классом на другую машину? C++
C++ Потоковый ввод / вывод файлов
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
palva
 Аватар для palva
2373 / 1595 / 190
Регистрация: 08.06.2007
Сообщений: 6,364
Записей в блоге: 4
31.01.2014, 14:10     Потоковый ввод из файла вместе с классом. Не пойму в чем причина #2
Вижу, что под planets вы выделяете место для одной планеты.
Но почему вы не приводите главную программу? С какими параметрами вы обращаетесь к функции read?
Nozi
0 / 0 / 0
Регистрация: 31.01.2014
Сообщений: 5
31.01.2014, 14:27  [ТС]     Потоковый ввод из файла вместе с классом. Не пойму в чем причина #3
palva, надо было закинуть все, согласен


Man.h
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
#pragma once
 
 
class Man
{
public:
    Man (char*,float,bool,int,int l_name=30);
    void name(int , char*,int&);
    char* get_name(int&);
    void metr(float);
    float get_metr();
    void snic(int);
    int get_snic();
    void sLife(bool);
    bool get_sLife();
    void save(int&);
    
    
 
    ~Man()
        { delete [] pName; }// деструктор
private:
    
    char* pName;
    float   diam;
    int sput;
    bool life;
 
 
};
Man.cpp

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
#include "Man.h"
#include <fstream>
 
 
char kolN[30][30];
int i=0;
 
Man::Man(char* pName, float diam, bool life, int sput,int l_name)
{
    Man::name(l_name,pName,i);
    Man::metr(diam);
    Man::sLife(life);
    Man::snic(sput);
}
 
void Man::name(int l_name, char* newName,int& i) 
{
    
    
    pName = new char[l_name];
    pName=newName;
    
    strcpy(kolN[i],pName);
}
 
char* Man::get_name(int &i)
{
    return kolN[i];
}
 
void Man::metr(float newDm)
{
    Man::diam=newDm;
}
 
float Man::get_metr()
{
    return Man::diam;
}
 
void Man::sLife(bool lifeS)
{
    Man::life=lifeS;
}
 
bool Man::get_sLife()
{
    return Man::life;
}
 
void Man::snic(int snicT)
{
    Man::sput=snicT;
}
 
int Man::get_snic()
{
    return Man::sput;
}
 
void Man::save(int& i)
{
    std::ofstream saveS("planetaS.txt",std::ios::app);
 
    saveS<<Man::get_name(i)<<"  "
        <<Man::get_metr()<<"  "
        <<Man::get_sLife()<<"  "
        <<Man::get_snic()<<std::endl;
 
    saveS.close();
}
и class.cpp

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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#include <iostream>
#include<fstream>
#include <iomanip>
#include "Man.h"
using namespace std;
 
 
int  menu()
{
    int a;
    cout<<"Выберите один из пунктов"<<endl
        <<"1)  Чтение БД 'Солнечная система' из файла"<<endl
        <<"2)  Запись БД 'Солнечная система' в файл"<<endl
        <<"3)  Сортировка БД"<<endl
        <<"4)  Редактировать БД 'Солнечная система'"<<endl
        <<"5)  Вывод БД на экран"<<endl
        <<"6) Выход!"<<endl;
    cin>>a;
    return a;
}
 
 
int read(char* file_name, Man planets[], char* pName,float diam,bool life, int sput, int l_name, int& kol_planet)
{   
    ifstream plan(file_name);
    
    while (plan)
    {
        
        plan>>pName;
            planets[kol_planet].name(l_name,pName,kol_planet);
        plan>>diam;
            planets[kol_planet].metr(diam);
        plan>>life;
            planets[kol_planet].sLife(life);
        plan>>sput;
            planets[kol_planet].snic(sput);
        kol_planet++;
        
    }
    
    cout<<endl<<"Прочитано!"<<endl;
    return kol_planet;
}
 
void write(char* file_name,Man planets[], int &kol_planet)
{
    int& i= kol_planet;
    for (int j=0;j<i;j++)
    {
        planets[j].save(j);
    }
 
    
    cout<<"БД обновлена!"<<endl;
}
 
void sort(Man planets[],int &kol_planet)
{
     int& i= kol_planet;
    for (int j=0;j<i;j++)
    {
        for (int q=0;q<i;q++)
        {
            if  (strcmp(planets[j].get_name(q),planets[q].get_name(q))>0) //сравниваю строки
            {
                swap(planets[j],planets[j+1]); //меняю местами в порядке возрастания
            }
        }
    }
}
 
int redakt(Man planets[],int &kol_planet, char* pName,float diam,bool life, int sput, int l_name )
{
 
 
    int k;
    char* name;
    name = new char [30];
    cout<<"Удалить запись [1] / Добавить запись [2] "<<endl;
    cin>>k;
 
    switch (k)
    {
    case 1:
        {
            cout<<"Введите название планеты"<<endl;
            cin>>name;
            for (int i=0;i<kol_planet;i++)
            {
                if (strcmp(name,planets[i].get_name(i))==0)
                {
                    
                        planets[i].get_name(i)=='\0';
                        planets[i].get_metr()=='\0';
                        planets[i].get_sLife()=='\0';
                        planets[i].get_snic()=='\0';
                    
                }
            }
            cout<<"Запись удалена!"<<endl;
        }
 
    case 2:
        {
            cout<<"Введите название планеты"<<endl;
            cin>>pName;
            planets[kol_planet].name(l_name,pName,kol_planet);
            cout<<"Ввеедите диаметр планеты"<<endl;
            cin>>diam;
            planets[kol_planet].metr(diam);
            cout<<"Существует ли на ней жизнь? Введите false/true"<<endl;
            cin>>life;
            planets[kol_planet].sLife(life);
            cout<<"Введите количество спутников"<<endl;
            cin>>sput;
            planets[kol_planet].snic(sput);
            cout<<"Планета добавлена в БД!"<<endl;
            kol_planet++;
        }
    }
    return kol_planet;
}
 
void outp(Man planets[],int &kol_planet)
{
    for (int i=0;i<kol_planet;i++)
    {
        cout<<endl;
            cout<<planets[i].get_name(i)<<"  ";
            cout<<planets[i].get_metr()<<"  ";
            cout<<planets[i].get_sLife()<<"  ";
            cout<<planets[i].get_snic()<<"  ";
    }
    cout<<endl;
}
 
 
 
 
 
 
 
 
int l_name=30;
const int Size = 10;
const int l_record = 80; 
char* pName=new char [l_name];
float   diam;
int sput;
bool life;
 
Man *planets=new Man(pName,diam,life,sput,l_name);
 
 
 
int main() 
{
    setlocale(0,"rus");
char *file_name = "planeta.txt";
int l;
int kol_planet=0;
 
while (true)
     { l=menu();
    switch (l) 
    {
    case 1:kol_planet=read(file_name,planets,pName,diam,life,sput,l_name,kol_planet);
            break; 
    case 2: write(file_name,planets,kol_planet); break;
    case 3: sort(planets,kol_planet); break;
    case 4: redakt(planets,kol_planet,pName,diam,life,sput,l_name); break; 
    case 5: outp(planets,kol_planet); break;
    case 6: return 0;
    default: cout<<" Неправильный ввод"<<endl; break;
    }
 }
system ("pause");
return 0;
}
Часть где удаление записей прошу не смотреть, еще разберусь как это сделать)
Да я создаю для одной планеты, но названия записываю в двумерный массив kolN. Если вводить данные с клавиатуры, то у меня сохраняются все записи для каждой планеты, а с файла вытащить не получается(
palva
 Аватар для palva
2373 / 1595 / 190
Регистрация: 08.06.2007
Сообщений: 6,364
Записей в блоге: 4
31.01.2014, 14:32     Потоковый ввод из файла вместе с классом. Не пойму в чем причина #4
Вопрос остался. При обращении к read параметр planets это указатель на 1 экземпляр объекта Man, а функция считает, что там целый массив.
Nozi
0 / 0 / 0
Регистрация: 31.01.2014
Сообщений: 5
31.01.2014, 14:37  [ТС]     Потоковый ввод из файла вместе с классом. Не пойму в чем причина #5
Как тогда правильно написать?

Добавлено через 3 минуты
Если сделать в параметрах функции
C++
1
Man *planets
то все так же остается, или я всеравно не понял?)
palva
 Аватар для palva
2373 / 1595 / 190
Регистрация: 08.06.2007
Сообщений: 6,364
Записей в блоге: 4
31.01.2014, 14:44     Потоковый ввод из файла вместе с классом. Не пойму в чем причина #6
Может я тоже не во всем разобрался. Вам нужно выделить память под массив объектов и с этим массивом обратиться к read. Но вы ведь неспроста выделили память только под один объект. Вы считаете, что это правильно? Тогда объясните, что имеется в виду.
Цитата Сообщение от Nozi Посмотреть сообщение
Как тогда правильно написать?
Вы не написали что вы хотите. Можно выделить память под массив, а можно переписать функцию read, чтоб она работала только с первым элементом массива.
Nozi
0 / 0 / 0
Регистрация: 31.01.2014
Сообщений: 5
31.01.2014, 14:56  [ТС]     Потоковый ввод из файла вместе с классом. Не пойму в чем причина #7
Да, изначально хотел выделить память под массив, но читая разный материал, написал именно так, только разбираюсь в конструкторах и деструкторах.
Значит из за того,что у меня память под один элемент, то и записывается только 1 строка?
И да, как тогда написать конструктор и само объявление под массив?
palva
 Аватар для palva
2373 / 1595 / 190
Регистрация: 08.06.2007
Сообщений: 6,364
Записей в блоге: 4
31.01.2014, 15:13     Потоковый ввод из файла вместе с классом. Не пойму в чем причина #8
Цитата Сообщение от Nozi Посмотреть сообщение
И да, как тогда написать конструктор и само объявление под массив?
Выделяете память под массив и пишете размер массива, например
C++
1
Man *planets=new Man[10];
при этом будет вызван конструктор по умолчанию. А уже потом организуете цикл, который для каждого элемента вызовет нужный вам конструктор. Если вам действительно это нужно.

Но у вас возникнет другая проблема. Вы не знаете сколько планет будет на вводе и сколько элементов массива выделять. Вы можете выделить с запасом, но если на вводе будет больше элементов, чем выделено на самом деле, то избыточный ввод налезет на другие данные и поведение программы будет непредсказуемо.
Nozi
0 / 0 / 0
Регистрация: 31.01.2014
Сообщений: 5
31.01.2014, 15:29  [ТС]     Потоковый ввод из файла вместе с классом. Не пойму в чем причина #9
Ну это не принципиально важно, много точно не будет, я делаю это в пример, изначально 9 планет, добавлю еще 3, покажу удаление и т.д.
Я сделал такой массив, прошлый конструктор заккоментировал.

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

у меня есть книга Шилдта, у него и узнал про while (plan).
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.01.2014, 16:10     Потоковый ввод из файла вместе с классом. Не пойму в чем причина
Еще ссылки по теме:

Потоковый ввод/вывод текста C++
C++ потоковый ввод и вывод строки С++
Потоковый ввод/вывод C++

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

Или воспользуйтесь поиском по форуму:
palva
 Аватар для palva
2373 / 1595 / 190
Регистрация: 08.06.2007
Сообщений: 6,364
Записей в блоге: 4
31.01.2014, 16:10     Потоковый ввод из файла вместе с классом. Не пойму в чем причина #10
Скорее всего где-то портится память. Но в коде разобраться трудно. Очень сложно и нелогично (для меня) написано.
Yandex
Объявления
31.01.2014, 16:10     Потоковый ввод из файла вместе с классом. Не пойму в чем причина
Ответ Создать тему
Опции темы

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