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

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

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

С++ класс и чтение из файла - C++

05.05.2013, 15:38. Просмотров 933. Ответов 11
Метки нет (Все метки)

Доброго времени суток.
Возник такой вот вопросец: "А как переменным из класса присвоить значения, которые мы прочитаем из файла?"
Т.е имеем класс:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class CAir
{
public:
    double R0;
    double Length;
    double th;
/**  Конструкторы класса */
    CAir();
    CAir(double R0,double Length,double th)
    {
        CAir::R0=R0;
        CAir::Length=Length;
        CAir::th=th;
    };
};
В файле .cpp я объявляю глобальные переменные: R0, Length, thetha;
В которые из файла считываю значения:
C++
1
2
3
4
5
6
while(!file_in.eof())
{
file_in >> R0;
file_in >> Length;
file_in >> thetha;
}
Пытаюсь создать в глобальной области видимости создать CAir Model(R0,Length,thetha);

Ничего не получается толкового из этого, объясните что не так делаю.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.05.2013, 15:38
Здравствуйте! Я подобрал для вас темы с ответами на вопрос С++ класс и чтение из файла (C++):

C++ чтение из файла в класс - C++
Файл test.txt n1 01 e1 0.1 n2 02 e2 0.2 n3 03 e3 0.3 n4 04 e4 0.4 n5 05 e5 0.5 n6 06 e6 0.6 n7 07 e7 0.7 n8 08 e8 0.8

Класс и чтение из файла - C++
У моего задания номер 5. (оно связано с заданием 4) 4. Реализуйте класс, для которого оператор перегружен, чтобы выполнять...

Класс. Строка. Чтение из файла. - C++
Добрый день. Возникла проблемка. #include <iostream> using namespace std; class zdanie { int plosh, obm; char *adres,...

Класс работы с массивами и чтение из файла - C++
Нужна помощь в решении задачи : Заданы 2 бинарных файла со следующей структурой: N - число эл-тов одномерного целочисленного...

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

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

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
metaluga145
243 / 244 / 20
Регистрация: 08.04.2013
Сообщений: 927
05.05.2013, 15:59 #2
Лучше уже писать вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class CAir
{
public:
    double R0;
    double Length;
    double th;
/**  Конструкторы класса */
    CAir();
    CAir(double R0,double Length,double th):
        R0(R0), Length(Length), th(th)
    {
    };
};
Добавлено через 1 минуту
в каком .cpp файле Вы пишите и что именно Вы там пишите?

Добавлено через 36 секунд
Зачем Вам глобальные переменные?
0
lemegeton
2924 / 1353 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
05.05.2013, 16:03 #3
Цитата Сообщение от StaR0sTa Посмотреть сообщение
А как переменным из класса присвоить значения, которые мы прочитаем из файла?
А с помощью сеттеров у класса.
Еще можно ко всему этому прикрутить операторы ввода-вывода для большей кошерности.
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
#include <fstream>
#include <iostream>
#include <iomanip>
 
class CAir {
 public:
  CAir() {}
  CAir(double r0, double length, double th) : r0(r0), length(length),
    th(th) {}
  double getR0() const { return r0; }
  double getLength() const { return length; }
  double getTh() const { return th; }
 
  void setR0(double r0) { this->r0 = r0; }
  void setLength(double length) { this->length = length; }
  void setTh(double th) { this->th = th; }
 
 private:
  double r0, length, th;
};
 
std::ostream &operator<<(std::ostream &stream, const CAir &cair) {
  return stream << "CAir{" <<
    std::fixed << std::setprecision(3) <<
    "r0=" << cair.getR0() << "," <<
    "length=" << cair.getLength() << "," <<
    "th=" << cair.getTh() << "}";    
}
 
std::ostream &operator<<(std::ofstream &stream, const CAir &cair) {
  return stream << cair.getR0() << " " << cair.getLength() << " " <<
    cair.getTh();
}
 
std::istream &operator>>(std::ifstream &stream, CAir &cair) {
  // для большей кошерности надо бы написать отдельную функцию для
  // чтения каждого типа данных вроде
  // double getDouble(std::ifstream &stream) { double value; stream >> value; return value; }
  // но для примера сойдет
  double value;
  stream >> value;
  cair.setR0(value);
  stream >> value;
  cair.setLength(value);
  stream >> value;
  cair.setTh(value);
  return stream;
}
 
int main(int argc, char *argv[]) {
  CAir cair(0.23, 0.32, 1.17);
  std::cout << cair << std::endl;
 
  std::ofstream out("file.txt");
  out << cair;
  out.close();
 
  std::ifstream in("file.txt");
  in >> cair;
  in.close();
  
  std::cout << cair << std::endl;
  return 0;
}
Добавлено через 3 минуты
Ну и было бы совсем прекрасно, если бы вы писали интуитивно понятные имена идентификаторов и придерживались бы одного code-style'а.
1
StaR0sTa
0 / 0 / 0
Регистрация: 01.05.2013
Сообщений: 12
05.05.2013, 16:27  [ТС] #4
Спасибо, учту=)
Глобальными я их объявляю, потому-что это объект используется во многих функциях..
В main.cpp всё пишу. Объявляю глобально этот объект:
CAir Model(R0,Length,thetha);
В этом же файле объявлены переменные R0,Length,thetha, значения которых я присваиваю из файла.
Но вот после этого, эти значения не хотят присваиваться Model, как-то так.

Добавлено через 11 минут
lemegeton вы изменили мой класс до неузнаваемости=) Я просто только учусь..оказалось всё не так просто, как того хотел бы я=) Проще присвоить явно значения, чтобы вызвался конструктор..и никаких проблем=) Но охото сделать красивее, так что спасибо за советы, сейчас разберусь в том что вы написали.

Добавлено через 10 минут
Ещё один вопрос..если в файле находится больше значений, чем 3..
Если написать:
C++
1
2
3
4
5
6
7
while(!file_in.eof())
{
in >> cair;
in >> a;
in >> b;
in >> c;
}
Он первые три присвоит объекту, а все остальные значения переменным по порядку?
0
lemegeton
2924 / 1353 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
05.05.2013, 16:42 #5
Цитата Сообщение от StaR0sTa Посмотреть сообщение
вы изменили мой класс до неузнаваемости=) Я просто только учусь.
Да учитесь ради Б-га. Для того и стараемся.

Цитата Сообщение от StaR0sTa Посмотреть сообщение
Проще присвоить явно значения, чтобы вызвался конструктор..и никаких проблем=)
Это называется неизменяемыми объектами (immutable). Есть такая хорошая практика -- делать небольшие объекты неизменяемыми. Тогда с ними гораздо удобнее работать, зная, что их свойства не изменятся в процессе работы. У этой техники есть и недостатки -- например, увеличивается объем памяти, необходимой для работы. Но, как известно, стоимость разработки превыше любых технических требований результата.

Кликните здесь для просмотра всего текста
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
#include <fstream>
#include <iostream>
#include <iomanip>
 
class CAir {
 public:
  CAir() {}
  CAir(double r0, double length, double th) : r0(r0), length(length),
    th(th) {}
  double getR0() const { return r0; }
  double getLength() const { return length; }
  double getTh() const { return th; }
 private:
  double r0, length, th;
};
 
std::ostream &operator<<(std::ostream &stream, const CAir &cair) {
  return stream << "CAir{" <<
    std::fixed << std::setprecision(3) <<
    "r0=" << cair.getR0() << "," <<
    "length=" << cair.getLength() << "," <<
    "th=" << cair.getTh() << "}";    
}
 
std::ostream &operator<<(std::ofstream &stream, const CAir &cair) {
  return stream << cair.getR0() << " " << cair.getLength() << " " <<
    cair.getTh();
}
 
std::istream &operator>>(std::ifstream &stream, CAir &cair) {
  double r0, length, th;
  stream >> r0 >> length >> th;
  cair = CAir(r0, length, th);
  return stream;
}
 
int main(int argc, char *argv[]) {
  CAir cair(0.23, 0.32, 1.17);
  std::cout << cair << std::endl;
 
  std::ofstream out("tutor5020.txt");
  out << cair;
  out.close();
 
  std::ifstream in("tutor5020.txt");
  in >> cair;
  in.close();
  
  std::cout << cair << std::endl;
  return 0;
}


Цитата Сообщение от StaR0sTa Посмотреть сообщение
Ещё один вопрос..если в файле находится больше значений, чем 3..
Смотря в чем суть вопроса. Если суть в том, как увеличить количество переменных класса, то с эта модификация должна лечь на плечи операторов ввода-вывода.

Кликните здесь для просмотра всего текста
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
#include <fstream>
#include <iostream>
#include <iomanip>
 
class CAir {
 public:
  CAir() {}
  CAir(double r0, double length, double th, double a) : r0(r0), length(length),
    th(th), a(a) {}
  double getR0() const { return r0; }
  double getLength() const { return length; }
  double getTh() const { return th; }
  double getA() const { return a; }
 private:
  double r0, length, th, a;
};
 
std::ostream &operator<<(std::ostream &stream, const CAir &cair) {
  return stream << "CAir{" <<
    std::fixed << std::setprecision(3) <<
    "r0=" << cair.getR0() << "," <<
    "length=" << cair.getLength() << "," <<
    "th=" << cair.getTh() << "," <<
    "a=" << cair.getA() << "}";
}
 
std::ostream &operator<<(std::ofstream &stream, const CAir &cair) {
  return stream << cair.getR0() << " " << cair.getLength() << " " <<
    cair.getTh() << " " << cair.getA() << " ";
}
 
std::istream &operator>>(std::ifstream &stream, CAir &cair) {
  double r0, length, th, a;
  stream >> r0 >> length >> th >> a;
  cair = CAir(r0, length, th, a);
  return stream;
}
 
int main(int argc, char *argv[]) {
  CAir cair(0.23, 0.32, 1.17, 2.15);
  std::cout << cair << std::endl;
 
  std::ofstream out("tutor5020.txt");
  out << cair;
  out.close();
 
  std::ifstream in("tutor5020.txt");
  in >> cair;
  in.close();
  
  std::cout << cair << std::endl;
  return 0;
}


Добавлено через 5 минут
Цитата Сообщение от StaR0sTa Посмотреть сообщение
Он первые три присвоит объекту, а все остальные значения переменным по порядку?
Да.
1
StaR0sTa
0 / 0 / 0
Регистрация: 01.05.2013
Сообщений: 12
05.05.2013, 17:15  [ТС] #6
Нет, суть не в том, чтобы увеличить количество переменных класса, а например если есть другие переменные, не зависящие от класса, которым из того же файла нужно присвоить значения.

Добавлено через 33 секунды
Это я и хотел узнать, спасибо =)) Сейчас буду пробовать.

Добавлено через 6 минут
Блин, наверное никогда не сделаю..написал:
C++
1
2
3
4
5
6
    while(!file_in.eof())
    {
        file_in >> Model;
        file_in >> dx;
        file_in >> dy;
            }
Я пошагово проверил, он присвоил значения верно, но почему то после прохода цикла, он прошёл ещё раз его..и изменил все значения на бред какой-то. Почему он два раза проходит этот цикл? В файле написано :
10 0.67 0.3 0.1 0.5

Добавлено через 20 минут
Всё правильно работает, если заменить
C++
1
while
на
C++
1
if
. Странно, но ответ на вопрос хотелось бы услышать=)
0
lemegeton
2924 / 1353 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
05.05.2013, 17:22 #7
Если вы использовали мой кусок кода, то в конце файла образовался сепаратор (пробел или конец строки). Это как раз говорит, что у файла еще не конец. ... и цикл едет считывать уже из ничего.
Вот я, лично, не знаю корректного способа работать с файлами в С++. Найдете -- напишите.

Простейший способ -- проверять, что файлу конец сразу после считывания. Если конец -- считанные данные не валидны.
C++
1
2
3
4
5
6
7
8
9
10
while(!file_in.eof()) {
  file_in >> Model;
  file_in >> dx;
  file_in >> dy;
  if (file_in.eof()) {
    // обрабатываем ситуацию, когда считанное не валидно
  } else {
    // данные валидны, работаем с ними
  }
}
0
abit
264 / 262 / 33
Регистрация: 03.02.2013
Сообщений: 730
05.05.2013, 17:29 #8
lemegeton,
Вот я, лично, не знаю корректного способа работать с файлами в С++. Найдете -- напишите.
функция std::istream::read

указываете приведённый к (char *) адрес на элемент структуры куда читать первым параметром, вторым - размер структуры в байтах (sizeof())
невалидность как структуры вернётся флагом, а уж сами данные - то тут стандартная защита от дурака должна быть

это самый нормальный способ, аналогичен паскалевским типизированным файлам
Pascal
1
2
3
4
5
  ...
  inputF : file of myrecord;
  Rec : myrecord;
  ...
  Read(inputF,Rec);
0
StaR0sTa
0 / 0 / 0
Регистрация: 01.05.2013
Сообщений: 12
05.05.2013, 17:36  [ТС] #9
А можно как-нибудь в файле, откуда читаем оставлять комментарии? Типо:
1 //Один
2 //Два
3 //Три
0
lemegeton
2924 / 1353 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
05.05.2013, 17:46 #10
Цитата Сообщение от abit Посмотреть сообщение
указываете приведённый к (char *) адрес на элемент структуры куда читать первым параметром, вторым - размер структуры в байтах (sizeof())
невалидность как структуры вернётся флагом, а уж сами данные - то тут стандартная защита от дурака должна быть
Так еще сложнее будет десериализовывать составные структуры данных типа классы с виртуальными методами или классы -- контейнеры, или классы, включающие в себя другие классы, особенно классы STL.

Добавлено через 1 минуту
Цитата Сообщение от StaR0sTa Посмотреть сообщение
А можно как-нибудь в файле, откуда читаем оставлять комментарии? Типо:
1 //Один
2 //Два
3 //Три
Да все возможно. Вопрос в сложности решения. Вот ваша хочушка ведет к тому, что надо считывать из файла строку, анализировать и потом вычленять из неё данные. Совершенно другая задача. Для вас пока скорее всего непосильная.
0
StaR0sTa
0 / 0 / 0
Регистрация: 01.05.2013
Сообщений: 12
05.05.2013, 17:49  [ТС] #11
Точно подмечено, непосильная..спасибо, обойдусь без этого значит=) Итак здорово мне помогли.
0
abit
264 / 262 / 33
Регистрация: 03.02.2013
Сообщений: 730
05.05.2013, 17:51 #12
lemegeton,
десериализовывать составные структуры данных типа классы с виртуальными методами или классы -- контейнеры, или классы, включающие в себя другие классы.
оО ???
приведите пример или смысл сброса в файл класса с виртуальным методом, мне что-то в голову не приходит...

далее если класс включает класс, он войдёт целиком и полностью как положено в структуру и её размер
насчёт контейнеров и методов в частности - нужно по хорошему сделать в классе функции чтения/запись в/из потока всех нужных полей класса через перегрузку операторов >> и <<
лучше ничего тут не придумать
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.05.2013, 17:51
Привет! Вот еще темы с ответами:

Преобразование текстового файла в двоичный и чтение исходных данных из двоичного файла. - C++
#include&lt;iostream&gt; #include&lt;fstream&gt; #include&lt;locale.h&gt; #include&lt;iomanip&gt; #include &lt;cstdlib&gt; using namespace std; struct...

Чтение нескольких структур и одной переменной из бинарного файла. Формат файла имеется - C++
Формат файла состоит из 3 структур и одной переменной. Подробное описание формата во вложении, просьба посмотреть его. У меня возникла...

как может корректно выполняющийся оператор >> (чтение из текстового файла) негативно влиять на открытие другого файла? - C++
Друзья! Создадим два текстовых файла, f_0.txt и f_1.txt и что-нибудь в них запизаем, например в первый запихаем 1234 а во второй 5678 и...

Чтение файла с несколькими знаками конца файла - C++
В файле несколько раз встречается ноль, и ни как не получается прочитать его полностью. Как можно решить данную проблему ?


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

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

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