Премини към съдържанието
Petur Dimitrov

Проблем с кода на сортировката.

Препоръчан отговор


Здравейте! Имам проблем с кода на сортировка постоянно ми крашва програмата когато стигне до алгоритъма.

 

void student::insertionsort(student* array, int n)
{
	student temp = array[0];
	for (int i = 0; i<n; i++)
	{
		char x = array[i].name[0];
		temp = array[i];
		int j = i - 1;
		while (j >= 0 && array[j].name[0] > x)
		{
			array[j + 1] = array[j];
			j--;
		}
		array[j + 1] = temp;
	}
}

Ако може да ми кажете от къде точно идва проблема ?

Това ми е в main()

group[0].insertionsort(group, n);

 

Когато дебъгера ми се отвори ми сочи този ред от кода.

        char x = array.name[0];
 

Редактирано от Petur Dimitrov (преглед на промените)

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Почти съм сигурен, че insertionsort(0, n) крашва програмата. student * e показател към променлива от тип student, a и подаваш стойност 0. Това си води до crash. Не мога да помогна без повече информация какъв тип е gorup[0] и като цяло няма нужда insertionsort да е част от класа student. И защо сортираш само по първия знак от name?

Сортираш по първия знак в името, но напълно е възможно името да е празно. Предполагам е string. Ако се опиташ да достатъпиш първия знак на празен string това води до грешка в програмата, защото не е заделено място в паметта.

Редактирано от plamenbm86 (преглед на промените)

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Това ми е целият код на програмата. Трябва алгоритъма да ми ги сортира по азбучен ред.

#include "stdafx.h"
#include <iostream>
#include <string.h>
#include <fstream>

using namespace std;

class person
{
protected:
	char *name;
	char *surname;
	char *fname;
	char *egn;
	long int number;

public:
	person();
	person& operator=(const person &p);
	void output();
	~person();
};

person::person()
{
	char buffer[30];

	cout << "Name:";
	cin >> buffer;
	name = new char[strlen(buffer) + 1];
	strcpy(name, buffer);

	cout << "Surname:";
	cin >> buffer;
	surname = new char[strlen(buffer) + 1];
	strcpy(surname, buffer);

	cout << "Family:";
	cin >> buffer;
	fname = new char[strlen(buffer) + 1];
	strcpy(fname, buffer);

	cout << "EGN:";
	cin >> buffer;
	egn = new char[strlen(buffer) + 1];
	strcpy(egn, buffer);

	cout << "Number:";
	cin >> number;
}

void person::output()
{
	cout << "Name:" << name << endl;
	cout << "Surname:" << surname << endl;
	cout << "Family:" << fname << endl;
	cout << "EGN:" << egn << endl;
	cout << "Number:" << number << endl;
}

person::~person()
{
	delete[] name;
	delete[] surname;
	delete[] fname;
	delete[] egn;
}

class student :public person
{
private:
	long int fnumber;
	char *spec;
	double GPA;
public:
	student();
	~student();
	friend void show(student *a, int n);
	friend void File(student *gp, int size);
	void insertionsort(student* a, int n);
};

student::student()
{
	char buffer[30];

	cout << "specialnost:";
	cin >> buffer;
	spec = new char[strlen(buffer) + 1];
	strcpy(spec, buffer);

	cout << "fac. nomer: ";
	cin >> fnumber;

	cout << "GPA:";
	cin >> GPA;
}


student::~student()
{
	delete[] spec;
}

void  File(student *gp, int size)
{
	ofstream file;
	file.open("group.txt");
	for (int i = 0; i<size; i++)
	{
		file << "Name: " << gp[i].name << endl;
		file << "Surname: " << gp[i].surname << endl;
		file << "Family: " << gp[i].fname << endl;
		file << "EGN: " << gp[i].egn << endl;
		file << "Number: " << gp[i].number << endl;
		file << "fac. nomer: " << gp[i].fnumber << endl;
		file << "specialnost: " << gp[i].spec << endl;
		file << "GPA: " << gp[i].GPA << endl;
	}
	file.close();
}

person& person::operator=(const person &p)
{
	if (this != &p)
		delete name;
	delete surname;
	delete fname;
	delete egn;

	name = new char[strlen(p.name) + 1];
	strcpy(name, p.name);

	surname = new char[strlen(p.surname) + 1];
	strcpy(surname, p.surname);

	fname = new char[strlen(p.fname) + 1];
	strcpy(fname, p.fname);

	egn = new char[strlen(p.egn) + 1];
	strcpy(egn, p.egn);
	return *this;
}

void show(student* a, int n)
{
	for (int i = 0; i<n; i++)
	{
		a[i].output();
	}
}



void student::insertionsort(student* a, int n)
{
	student temp = a[0];
	for (int i = 0; i < n; i++)
	{
		char x = a[i].name[0];
		temp = a[i];
		int j = i - 1;
		while (j >= 0 && a[j].name[0] > x)
		{
			a[j + 1] = a[j];
			j--;
		}
		a[j + 1] = temp;
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	int n;
	student *group;
	cout << "Count of students: ";
	cin >> n;
	group = new student[n];

	group[0].insertionsort(group, n);
	show(group, n);

	File(group, n);
	delete[] group;
	system("PAUSE");
	return 0;
}

Сега ми излиза следният дебъгер с това нещо ако може да ми помогнете да го оправя ? Имам съмнения че тези грешки ги дава от алгоритъма, но нямам да представа как да го оправя този проблем .

 

Снимка.PNG

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Ако студента се казва Pablo Diego José Francisco de Paula Juan Nepomuceno María de los Remedios Cipriano de la Santísima Trinidad Ruiz y Picasso как ще му запишеш името само в три полета?

 

Сподели този отговор


Линк към този отговор
Сподели в други сайтове
преди 1 час, ined написа:

Ако студента се казва Pablo Diego José Francisco de Paula Juan Nepomuceno María de los Remedios Cipriano de la Santísima Trinidad Ruiz y Picasso как ще му запишеш името само в три полета?

 

Такива дълги имена няма да използвам в програмата. Може ли да ми помогнеш алгоритъма да сортира само по трите имена по азбучен ред? Защото явно има някакви проблеми в сегашният алгоритъм и не иска да сортира имената нямам представа къде е грешката в алгоритъма.

Редактирано от Petur Dimitrov (преглед на промените)

Сподели този отговор


Линк към този отговор
Сподели в други сайтове
преди 16 часа, Petur Dimitrov написа:

Защото явно има някакви проблеми в сегашният алгоритъм

Всъщност, програмата ти е учебник по всички видове грешки, дето може да се направят в една програма с наследени класове и динамични ресурси....

  • Правилото за голямата тройка - където ти трябва поне едно от: деструктор, копиращ конструктор или оператор за присвояване, вероятно ти трябват и другите 2. Тук е точно така.
  • Предефиниран оператор за присвояване. Тези оператори са с експлицитни типове на параметрите и се правят за всеки клас по отделно, независимо от наследяването. Трябва да имаш и за наследения, а ако те мързи да пишеш код, си викай вътре оператора на базовия. Иначе, откъде да знае компилатора какво да копира?
  • Конструктор, дето въвежда данни от клавиатурата... ужас. Само да питам, замислил ли се, че като ползваш временен обект и той също се конструира?
  • оператор delete [] хубаво, че го знаеш, ама и да го ползваш навсякъде, където трябва, ще е хубаво.
  • Защитното условие в операторa за присвояване, трябва да се отнася за целия му код, не само за едното триене. Замисли се - ако трябва да присвоиш нещо на себе си, що ти трябва изобщо да правиш нещо? Ако указателите съвпадат, връщаш *this и толкоз.
  • ...

 

 

Редактирано от flare (преглед на промените)
  • Харесва ми 1

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Опасявам се, че такива глупости преподават в някои университети. Все пак си е някакво упражнение.

#include <iostream>
#include <string.h>
#include <fstream>

using namespace std;

class person
{
protected:
	char *name;
	char *surname;
	char *fname;
	char *egn;
	long int number;
    void assign(const person &p);

public:
	person();
    person(const person &p);
	person& operator=(const person &p);
	void output();
	~person();
    
    friend int compare_names(const person& a, const person& b);
    
};

person::person()
{
	char buffer[30];

	cout << "Name:";
	cin >> buffer;
	name = new char[strlen(buffer) + 1];
	strcpy(name, buffer);

	cout << "Surname:";
	cin >> buffer;
	surname = new char[strlen(buffer) + 1];
	strcpy(surname, buffer);

	cout << "Family:";
	cin >> buffer;
	fname = new char[strlen(buffer) + 1];
	strcpy(fname, buffer);

	cout << "EGN:";
	cin >> buffer;
	egn = new char[strlen(buffer) + 1];
	strcpy(egn, buffer);

	cout << "Number:";
	cin >> number;
}

person::person(const person &p)
{
    name = 0;
    surname = 0;
    fname = 0;
    egn = 0;
    assign(p);
}

void person::output()
{
	cout << "Name:" << name << endl;
	cout << "Surname:" << surname << endl;
	cout << "Family:" << fname << endl;
	cout << "EGN:" << egn << endl;
	cout << "Number:" << number << endl;
}

person::~person()
{
	delete[] name;
	delete[] surname;
	delete[] fname;
	delete[] egn;
}

int compare_names(const person& a, const person& b)
{
    int cmp = strcmp(a.name, b.name);
    if (cmp != 0) return cmp;
    cmp = strcmp(a.surname, b.surname);
    if (cmp != 0) return cmp;
    cmp = strcmp(a.fname, b.fname);
    return cmp;
}

class student :public person
{
private:
	long int fnumber;
	char *spec;
	double GPA;
    void assign(const student&);
public:
	student();
    student(const student &s);
	~student();
    student& operator=(const student &s);
	friend void show(student *a, int n);
	friend void File(student *gp, int size);
	friend void insertionsort(student* a, int n);
};

student::student()
{
	char buffer[30];

	cout << "specialnost:";
	cin >> buffer;
	spec = new char[strlen(buffer) + 1];
	strcpy(spec, buffer);

	cout << "fac. nomer: ";
	cin >> fnumber;

	cout << "GPA:";
	cin >> GPA;
}

student::student(const student& s): person(s)
{
    spec = 0;
    assign(s);
}


student::~student()
{
	delete[] spec;
}

void  File(student *gp, int size)
{
	ofstream file;
	file.open("group.txt");
	for (int i = 0; i<size; i++)
	{
		file << "Name: " << gp[i].name << endl;
		file << "Surname: " << gp[i].surname << endl;
		file << "Family: " << gp[i].fname << endl;
		file << "EGN: " << gp[i].egn << endl;
		file << "Number: " << gp[i].number << endl;
		file << "fac. nomer: " << gp[i].fnumber << endl;
		file << "specialnost: " << gp[i].spec << endl;
		file << "GPA: " << gp[i].GPA << endl;
	}
	file.close();
}

void person::assign(const person &p) { 
    delete name;
    delete surname;
    delete fname;
    delete egn;

    name = new char[strlen(p.name) + 1];
    strcpy(name, p.name);

    surname = new char[strlen(p.surname) + 1];
    strcpy(surname, p.surname);

    fname = new char[strlen(p.fname) + 1];
    strcpy(fname, p.fname);

    egn = new char[strlen(p.egn) + 1];
    strcpy(egn, p.egn);        
}

person& person::operator=(const person &p)
{
	if (this != &p) {
       assign(p); 
    }
	return *this;
}

void show(student* a, int n)
{
	for (int i = 0; i<n; i++)
	{
		a[i].output();
	}
}


void insertionsort(student* a, int n)
{
	for (int i = 1; i < n; i++)
	{
		student temp = a[i];
		int j = i - 1;
		while (j >= 0 && compare_names(a[j], temp) > 0)
		{
			a[j + 1] = a[j];
			j--;
		}
		a[j + 1] = temp;
	}
}

void student::assign(const student& s)
{
    delete spec;
    spec = new char[strlen(s.spec) + 1];
    strcpy(spec, s.spec);
}

student& student::operator=(const student& s) {
    if (this != &s) 
    {
        person::assign(s);
        assign(s);        
    }
    return *this;
}


int main()
{
	int n;
	student *group;
	cout << "Count of students: ";
	cin >> n;
	group = new student[n];

	insertionsort(group, n);
	show(group, n);

	File(group, n);
	delete[] group;
	system("PAUSE");
	return 0;
}

 

  • Харесва ми 1

Сподели този отговор


Линк към този отговор
Сподели в други сайтове
преди 3 часа, plamenbm86 написа:

Опасявам се, че такива глупости преподават в някои университети. Все пак си е някакво упражнение.

 

Ами честно да ти кажа както го бях написал го гледах от учебник на преподавател който ми води дисциплината и го написали така . Инак много ти благодаря работи и сега доста по - добре е направено и подредено кода, но каквото ни преподават в университета няма как да се промени. Също така много зависи и от преподаватели как ще те научат.

Сподели този отговор


Линк към този отговор
Сподели в други сайтове
на 10.12.2016 г. в 12:13, plamenbm86 написа:

Опасявам се, че такива глупости преподават в някои университети. Все пак си е някакво упражнение.


#include <iostream>
#include <string.h>
#include <fstream>

using namespace std;

class person
{
protected:
	char *name;
	char *surname;
	char *fname;
	char *egn;
	long int number;
    void assign(const person &p);

public:
	person();
    person(const person &p);
	person& operator=(const person &p);
	void output();
	~person();
    
    friend int compare_names(const person& a, const person& b);
    
};

person::person()
{
	char buffer[30];

	cout << "Name:";
	cin >> buffer;
	name = new char[strlen(buffer) + 1];
	strcpy(name, buffer);

	cout << "Surname:";
	cin >> buffer;
	surname = new char[strlen(buffer) + 1];
	strcpy(surname, buffer);

	cout << "Family:";
	cin >> buffer;
	fname = new char[strlen(buffer) + 1];
	strcpy(fname, buffer);

	cout << "EGN:";
	cin >> buffer;
	egn = new char[strlen(buffer) + 1];
	strcpy(egn, buffer);

	cout << "Number:";
	cin >> number;
}

person::person(const person &p)
{
    name = 0;
    surname = 0;
    fname = 0;
    egn = 0;
    assign(p);
}

void person::output()
{
	cout << "Name:" << name << endl;
	cout << "Surname:" << surname << endl;
	cout << "Family:" << fname << endl;
	cout << "EGN:" << egn << endl;
	cout << "Number:" << number << endl;
}

person::~person()
{
	delete[] name;
	delete[] surname;
	delete[] fname;
	delete[] egn;
}

int compare_names(const person& a, const person& b)
{
    int cmp = strcmp(a.name, b.name);
    if (cmp != 0) return cmp;
    cmp = strcmp(a.surname, b.surname);
    if (cmp != 0) return cmp;
    cmp = strcmp(a.fname, b.fname);
    return cmp;
}

class student :public person
{
private:
	long int fnumber;
	char *spec;
	double GPA;
    void assign(const student&);
public:
	student();
    student(const student &s);
	~student();
    student& operator=(const student &s);
	friend void show(student *a, int n);
	friend void File(student *gp, int size);
	friend void insertionsort(student* a, int n);
};

student::student()
{
	char buffer[30];

	cout << "specialnost:";
	cin >> buffer;
	spec = new char[strlen(buffer) + 1];
	strcpy(spec, buffer);

	cout << "fac. nomer: ";
	cin >> fnumber;

	cout << "GPA:";
	cin >> GPA;
}

student::student(const student& s): person(s)
{
    spec = 0;
    assign(s);
}


student::~student()
{
	delete[] spec;
}

void  File(student *gp, int size)
{
	ofstream file;
	file.open("group.txt");
	for (int i = 0; i<size; i++)
	{
		file << "Name: " << gp[i].name << endl;
		file << "Surname: " << gp[i].surname << endl;
		file << "Family: " << gp[i].fname << endl;
		file << "EGN: " << gp[i].egn << endl;
		file << "Number: " << gp[i].number << endl;
		file << "fac. nomer: " << gp[i].fnumber << endl;
		file << "specialnost: " << gp[i].spec << endl;
		file << "GPA: " << gp[i].GPA << endl;
	}
	file.close();
}

void person::assign(const person &p) { 
    delete name;
    delete surname;
    delete fname;
    delete egn;

    name = new char[strlen(p.name) + 1];
    strcpy(name, p.name);

    surname = new char[strlen(p.surname) + 1];
    strcpy(surname, p.surname);

    fname = new char[strlen(p.fname) + 1];
    strcpy(fname, p.fname);

    egn = new char[strlen(p.egn) + 1];
    strcpy(egn, p.egn);        
}

person& person::operator=(const person &p)
{
	if (this != &p) {
       assign(p); 
    }
	return *this;
}

void show(student* a, int n)
{
	for (int i = 0; i<n; i++)
	{
		a[i].output();
	}
}


void insertionsort(student* a, int n)
{
	for (int i = 1; i < n; i++)
	{
		student temp = a[i];
		int j = i - 1;
		while (j >= 0 && compare_names(a[j], temp) > 0)
		{
			a[j + 1] = a[j];
			j--;
		}
		a[j + 1] = temp;
	}
}

void student::assign(const student& s)
{
    delete spec;
    spec = new char[strlen(s.spec) + 1];
    strcpy(spec, s.spec);
}

student& student::operator=(const student& s) {
    if (this != &s) 
    {
        person::assign(s);
        assign(s);        
    }
    return *this;
}


int main()
{
	int n;
	student *group;
	cout << "Count of students: ";
	cin >> n;
	group = new student[n];

	insertionsort(group, n);
	show(group, n);

	File(group, n);
	delete[] group;
	system("PAUSE");
	return 0;
}

 

Извинявам се че пиша двоен коментар. Може ли да обясниш част от кода с коментари кое както прави ако може.

 

void assign(const person &p);

friend int compare_names(const person& a, const person& b);

person::person(const person &p)
{
    name = 0;
    surname = 0;
    fname = 0;
    egn = 0;
    assign(p);
}


int compare_names(const person& a, const person& b)
{
    int cmp = strcmp(a.name, b.name);
    if (cmp != 0) return cmp;
    cmp = strcmp(a.surname, b.surname);
    if (cmp != 0) return cmp;
    cmp = strcmp(a.fname, b.fname);
    return cmp;
}


student::student(const student& s): person(s)
{
    spec = 0;
    assign(s);
}

void person::assign(const person &p) { 

void student::assign(const student& s)
{
    delete spec;
    spec = new char[strlen(s.spec) + 1];
    strcpy(spec, s.spec);
}

student& student::operator=(const student& s) {
    if (this != &s) 
    {
        person::assign(s);
        assign(s);        
    }
    return *this;
}

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

void assign(const person &p) e функция, която присвоява динамично заделените полета на person. Освобождава паметта, ако има заделена преди това и заделя нова за стойностите, които присвоява. 

person::person(const person &p) е конструктор за присвояване. Необходим е за да можеш да направиш копие без да викаш стандартния конструктор, които изисква вход. Инициализира с 0 показателите към динамичните заделените стойности. Необходимо е защото delete крашва програмата, ако се извика на указател, който не сочи към заделена памет и не е 0.

int compare_names(const person& a, const person& b); сравнявя имената на два обекта person, като използва strcmp. При първата разлика в имената връща съответната разлика.

student(const student& s) е също конструктор за присвояване. Вика базовия конструктор за присвояване на person. В противен случай ще извика person(). Инициализира променливата spec.

void student::assign(const student& s) e версия на assign функцията за student. Тя копира само spec, защото тя сочи към допълнителната динамична памет.

student& student::operator=(const student& s) е оператор за присвояване за student. Първи вика базовия person::assign за членовете на person. После и student::assign.

 

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Регистрирайте се или влезете в профила си за да коментирате

Трябва да имате регистрация за да може да коментирате това

Регистрирайте се

Създайте нова регистрация в нашия форум. Лесно е!

Нова регистрация

Вход

Имате регистрация? Влезте от тук.

Вход

×

Информация

Поставихме бисквитки на устройството ви за най-добро потребителско изживяване. Можете да промените настройките си за бисквитки, или в противен случай приемаме, че сте съгласни с нашите условия за ползване.