Класс В С++

  • Автор темы Cruser
  • Дата начала
C

Cruser

#1
Здравствуйте, уважаемые программисты. Перехожу сразу к сути вопроса. Требуется описать класс с именем MARSH, содержащий следующие элементы:
  • Скрытые поля:
  • название начального пункта маршрута(char *)
  • название конечного пункта маршрута (char *)
  • номер наршрута (int)

  • Открытые методы:
  • конструктор по умолчанию
  • конструктор с параметрами для заполнения всех полей класса
  • конструктор копирования
  • деструктор
  • операция присваивания
  • операция сравнения "меньше"(операция возвращает истину, если номер маршрута у первого операнда меньше чем у второго)
  • операция сравнения на равенство с числом (операция возвращает истину, если номер маршрута совпадает с данным числом)
  • функция вывода на экран полей класса

Память для строк - полей класса выделять динамически.

С помощью текстового редактора создать файл и записать в него данные для массива из восьми элементов типа MARSH.

Написать программу, выполняющую следующие действия:
  • ввод из файла данных в динамический массив, состоящий из восми элементов типа MARSH
  • упорядочить массив по возрастанию номеров маршрута
  • вывод на экран информации о маршруте, номер которого веден с клавиатуры
  • если таких маршрутов нет, выдать на дисплей соответствующее сообщение

Часов 10 убил на составление данной программы, постоянно выдавала ошибки. В конце концов, все ошибки в коде были исправлены, при отладке ни на что не ругается, но при запуске самой программы выдает непонятную ошибку. Нигде про нее не могу найти информацию.
Вот сам код программы:
C++:
---------------------------------Marsh.cpp------------------------------------
#define _CRT_SECURE_NO_WARNINGS
#include "Marsh.h"
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;

Marsh::Marsh () //реализация конструктора по умолчанию - зануление полей
{
start=NULL;
finish=NULL;
number=0;
}

Marsh::Marsh (char *a, char* b, int c) //реализация конструктора с параметрами, в соответствие каждому полю ставим соответствующую переменную
{
if (a!=NULL)
{
start=new char [strlen(a)+1]; // выделение памяти для строки a
start=a; // копирование строки a в строку start
}
else start=NULL;
finish=NULL;
number=0;
if (b!=NULL)
{
finish=new char [strlen (b)+1]; //выделение памяти для строки b
finish=b; //копирование строки b в строку finish
}
else start=NULL;
finish=NULL;
number=0;
}

Marsh::Marsh (const Marsh &x) //реализация конструктора копирования
{
if (x.start!=NULL)
{
start=new char [strlen(x.start)+1];
start=x.start;
}
else start=NULL;
finish=NULL;
number=x.number;

if (x.finish!=NULL)
{
finish=new char [strlen(x.finish)+1];
finish=x.finish;
}
else start=NULL;
finish=NULL;
number=x.number;
}


Marsh::~Marsh () //деструктор
{
delete [ ] start;
delete [ ] finish;
}

Marsh &Marsh::operator= (Marsh &a) //реализация операции присваивания
{
delete [ ] start; //освобождение памяти для поля start
start=new char [strlen(a.start)+1];
start=a.start;
delete [ ] finish; //освобождение памяти для поля finish
finish=new char [strlen(a.finish)+1];
finish= a.finish;
number=a.number;
return *this;
}

bool Marsh::operator< (Marsh &b) //операция сравнения "меньше"
{
return number<b.number; //возвращает true или false
}

bool Marsh::operator== (int number) //операция сравнение на равенство с числом
{
if ((number<=8) & (number >=1)) return true;
else return false;
}

void Marsh::print() //функция вывода на экран
{
cout << "Nomer: " << number << " Nachalniy punkt:" << start << " Konechniy punkt:" << finish << endl;
}

void main ()
{

int i=0; //переменная-счётчик
Marsh*mass; //создание массива из элементов класса
mass=new Marsh[8]; //создание массива из элементов класса
FILE *f;
f=fopen("Marsh.txt", "rt"); //открытие файла
int p=sizeof(FILE);
if (p=0) cout << "File pust" << endl;
else
{
char a[50]; //переменная для записи в неё из файла символьной строки (название начального пункта)
char b[50]; //переменная для записи в неё из файла символьной строки (название конечного пункта)
int c=0; //переменная для записи в неё из файла целого числа (номер маршрута)

for (i=0; i<8; i++) //цикл записи из файла в массив
{
fscanf(f,"%s",a); //заполнение переменной a (строка)
fscanf(f,"%s",b); //заполнение переменной b (строка)
fscanf(f,"%d",&c); //заполнение переменной c (целое)
Marsh z(a,b,c); //инициализация с присвоением переменной z
mass[i]=z; //присвоение элементу массива значения полей z
mass[i].print(); //вывод на экран элемента массива

}
}
cout<<"\n";//отделение


Marsh tmp;//начало сортировки
for (i=0;i<8;i++)
{
int ind=i;
for (int j=i+1;j<8;j++)
{
if(mass[j]<mass[ind]) {ind=j;}
}

tmp=mass[i];
mass[i]=mass[ind];
mass[ind]=tmp;
}
for (i=0;i<8;i++) mass[i].print();//завершение сортировки и вывод отсортированного массива на экран


int q;int w=1;//переменная q - для ввода с клавиатуры, переменная w - для условия
do
{
cout << "Введите пункт назначения: " << endl;
cin >> q; //ввод с клавиатуры
for (i=0;i<8;i++) //поиск соответствующей строки среди массива
{
if (mass[i]==q) {mass[i].print();w=0;} //если строка найдена, w=0 и нужный элемент выводится на экран
}
if (w!=0) cout << "Net sootvetstvuyushego marshruta " << endl; //проверка нахождение строки
cout << "Dlya prodoljeniya najmite 5" << endl;//проверка на выход из функции
cin >> w;
}
while (w==10); //условие выхода из цикла
delete []mass; //освобождение памяти, зарезервированной для массива
}
А вот код заголовочного файла:
C++:
---------------------------Marsh.h------------------------------------
class Marsh
{
char* start; //символьная переменная
char* finish; //символьная переменная
int number; //целая переменная
public:
Marsh (); //конструктор по умолчанию
Marsh(char*, char*, int); //конструктор с параметрами для заполнения полей класса
Marsh (const Marsh&);//конструктор копирования
~Marsh();//деструктор
Marsh& operator= (Marsh&);//присваивание
bool operator< (Marsh&); //сравнение
bool operator== (int); //сравнение равенства с числом
void print(); //вывод на экран

};
На первом скриншоте скрин_1.png показывается то, что выдает мне программа после завершения отладки. На втором скрин_2.png то, что получается после запуска самой программы. Код перепроверял бесчисленное количество раз, но так и не получилось ничего сделать с вылетающей ошибкой. Программа написана в среде Microsoft visual studio 2010. Помогите решить проблему.
 

Вложения

R

rrrFer

#2
но при запуске самой программы выдает непонятную ошибку.
пройдись отладчиком и узнай на какой строке ошибка )

Добавлено:
Код:
FILE *f;
f = fopen("Marsh.txt", "rt"); //открытие файла
int p = sizeof (FILE);
if (p = 0) cout << "File pust" << endl;
сам-то понимаешь что тут? )
 
R

rrrFer

#3
напиши проверку отсутствия файла.

ты пишешь sizeof(FILE)... FILE - это тип, примерно такой же как int.

Во время компиляции sizeof заменяется на константу.

Есть подозрение что ты хочешь получить от sizeof размер файла на диске )

Добавлено: #define _CRT_SECURE_NO_WARNINGS
зачем это тут?

Добавлено:
Код:
 char* start; //символьная переменная
char* finish; //символьная переменная
int number; //целая переменная
комментарии писать научись. Они должны пояснять код, я и без комментария вижу int и понимаю что там целое, лучше бы пояснил чего там number и чего finish

Добавлено:
Код:
 Marsh*mass; //создание массива из элементов класса
mass = new Marsh[8]; //создание массива из элементов класса
зачем динамически память выделять, если всегда выделяешь под 8 элементов?
наверное чтобы потом случайно забыть освободить...

Добавлено:
Код:
bool Marsh::operator==(int number) //операция сравнение на равенство с числом
{
if ((number <= 8) & (number >= 1)) return true;
else return false;
}
на равенство с каким числом?
 
C

Cruser

#4
пройдись отладчиком и узнай на какой строке ошибка )
проходился - толку ноль. ни ошибок, ни предупреждений. на скрине видно

сам-то понимаешь что тут? )
хотел проверить наличие символов в файле. а это подразумевает наличие размера самого файла. больше ничего не приходит в голову.

программа ругалась на код fopen. что-то вроде устаревшей версии. по другому проблема не решалась.

на равенство с каким числом?
в файле нужно записать номера маршрутов и их путь от начального до конечного пункта. то есть вводишь цифру и программа выдает всю информацию о маршруте, если он существует. вот с числом, которое вводим с клавиатуры и идет сравнение.
 
R

rrrFer

#5
проходился - толку ноль. ни ошибок, ни предупреждений. на скрине видно
на скрине видно окно с ошибкой, на какой строке это окно появилось?
хотел проверить наличие символов в файле. а это подразумевает наличие размера самого файла. больше ничего не приходит в голову.
а это вообще ничего не подразумевает, абсолютно, это тоже самое что написать if (true)
программа ругалась на код fopen. что-то вроде устаревшей версии. по другому проблема не решалась.
скорее всего это были не ошибки, а предупреждения, это не особо мешает
в файле нужно записать номера маршрутов и их путь от начального до конечного пункта. то есть вводишь цифру и программа выдает всю информацию о маршруте, если он существует. вот с числом, которое вводим с клавиатуры и идет сравнение.
там идет сравнение с константами 1 и 8, причем, в классе есть поле number, но используется только аргумент. Нахрена этот метод заснули в класс вообще не понятно. Вы написали функцию которая возвращает true если 1 < аргумент < 8 и false в противном случае. Если это метод - то пусть он хоть статическим будет.

Добавлено: посмотри внимательно на свой код, удали его и напиши новый
Код:
Marsh::Marsh (const Marsh &x) //реализация конструктора копирования
{
if (x.start!=NULL)
{
start=new char [strlen(x.start)+1];
start=x.start;
}
else start=NULL;
finish=NULL;
number=x.number;

if (x.finish!=NULL)
{
finish=new char [strlen(x.finish)+1];
finish=x.finish;
}
else start=NULL;
finish=NULL;
number=x.number;
}
мне кажется или в этом небольшом и случайно выбранном фрагменте:
независимо от входных аргументов finish примет значение NULL
утекает память, т.к. сначала мы ее выделим: finish=new char [strlen(x.finish)+1];, а затем обнулим finish
2 раза выполняется number=x.number; (зачем 2?)
2 раза выполняется finish=NULL; (зачем 2?)

я не знаю что вы хотели достичь этим говнокодом, но он эквивалентен этому:
Код:
Marsh::Marsh (const Marsh &x) {
number=x.number;
start = finish = NULL;
if (x.start) {
start=new char [strlen(x.start)+1];
start=x.start;
}
}

Добавлено: кстати, если вы хотели скопировать строку - то вот это: start=x.start; выполнит не то что вы хотели.
копируйте с strcpy
 
C

Cruser

#6
Большое спасибо за советы и потраченное на мой пост время. Некоторые советы оказались полезными, но код все-таки пришлось переписать полностью.