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

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

Войти
Регистрация
Восстановить пароль
 
Nozi
0 / 0 / 0
Регистрация: 31.01.2014
Сообщений: 5
#1

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

31.01.2014, 13:44. Просмотров 334. Ответов 9
Метки нет (Все метки)

Привет народ. У меня такая проблема. Пишу лабораторную, и не могу таким способом (показан ниже) ввести всю таблицу и сохранить внутри программы. В этой лабораторной изучается раздел Классы, но видимо причина не в этом.
До этого делал лабораторную со структурой и такой же ввод с помощью 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++
Такой вопрос. Считываю данные из текстового файла с помощью потоков и записываю их в двусвязный список. В файле данных для 4 элементов...

Потоковый ввод и ввод данных. Работа с числами - C++
Ввести с экрана два нат. числа. Найти частное первого на второе и определить, встречается ли среду его дробной части цифра 3( рассматривать...

потоковый ввод - C++
всем привет! ситуация такая: при выполнении считываются только R2 и h, не могу понять, в чем дело. dev-c++ просто выдает &quot;step t =...

Потоковый ввод/вывод - C++
#include &lt;iostream&gt; #include &lt;stdio.h&gt; using namespace std; int main(int argc, char* argv) { FILE* in = fopen(&quot;xxx.txt&quot;,...

потоковый ввод с консоли - C++
Всем привет! Нужно в цикле вводить строки с консоли, пока пользователю не надоест. Вопрос: как пользователю завершить ввод? Такой код: ...

потоковый ввод - вывод - C++
всем доброго времени суток. мне вот недавно задали написать программу которая реализует несколько процедур стандартной библиотеки...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
palva
2609 / 1831 / 262
Регистрация: 08.06.2007
Сообщений: 6,989
Записей в блоге: 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
2609 / 1831 / 262
Регистрация: 08.06.2007
Сообщений: 6,989
Записей в блоге: 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
2609 / 1831 / 262
Регистрация: 08.06.2007
Сообщений: 6,989
Записей в блоге: 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
2609 / 1831 / 262
Регистрация: 08.06.2007
Сообщений: 6,989
Записей в блоге: 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).
palva
2609 / 1831 / 262
Регистрация: 08.06.2007
Сообщений: 6,989
Записей в блоге: 4
31.01.2014, 16:10 #10
Скорее всего где-то портится память. Но в коде разобраться трудно. Очень сложно и нелогично (для меня) написано.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.01.2014, 16:10
Привет! Вот еще темы с ответами:

Потоковый ввод-вывод - C++
Написать программу, которая будет добавлять в текстовый файл введенную с клавиатуры информацию Следует предусмотреть возможность выбора...

Потоковый ввод / вывод файлов - C++
Помогите пожайлуйста исправить ошибки в коде. В функции OemToChar пишет &quot;char*&quot; не совместим с параметром &quot;LPWSTR&quot; #include &quot;stdafx.h&quot; ...

Потоковый ввод/вывод текста - C++
Добрый день! Помогите пожалуйста разобраться. Почему при вводе текста в консоли, он сохраняется каракулями? #include &lt;cstdlib&gt; ...

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


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

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

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