Итак, вот вещи, которые мне еще нужно сделать. У меня возникли серьезные проблемы с синтаксисом. Я не знаю, почему я получаю сообщение об ошибке при попытке объявить динамически размещенный массив. Было бы здорово, если бы я мог получить некоторую помощь по этому вопросу.
BabyNames
учебный класс:
<<
) и извлечение (>>
) операторы. Вот шапка
/*
* File: BabyNames.h
* Author: jack
*
* Created on March 18, 2013, 3:35 PM
*/
#ifndef BABYNAMES_H_
#define BABYNAMES_H_
#include <string>
#include <fstream>
using namespace std;
using std::ifstream;
/**
* gender: an enum to hold types boy and girl
*/
enum gender {boy, girl};
/**
* PeopleStats: a data struct to hold year, name, double, and the enum type
* gender
*/
struct PeopleStats {
short year;
string name;
double percent;
gender sex;
};
/**
* Names: A class that reads data from a file into a PeopleStats Array
* and is capable of sorting them by name and by popularity percentage
*/
class BabyNames {
public:
BabyNames();
BabyNames(const char fn[], const int numLines);
gender parseSex(string s);
void swap(int i);
const int getCapacity();//getter for dataSize
const PeopleStats& get(int i) const; //getter for objects of the data array
void sortByName(); //Sorts the names alphabetically
void sortByPopularity();//Sorts the names by popularity
friend std::ostream& operator<<(std::ostream& os, const BabyNames& bn);
//friend std::PeopleStats& operator =(const PeopleStats& rhs);
private:
static const int MAX_DATA_SIZE = 25000;
PeopleStats* people;
int capacity;
int fillCount; // to keep track of how many array locations have data objects in them
static const int OUT_OF_BOUNDS = -1;
};//end of class
#endif /* BABYNAMES_H */
Вот функции
/**
* PeopleSort.cpp
* Description:
* This class stores the information in data structure and includes methods that
* sort the data by name and by popularity.
* Created:
* Feb 27, 2013
* Modified:
* March 1st 2013
*/
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
using std::ifstream;
#include "BabyNames.h"
/**
* BabyNames: A class that reads data from a file into a PeopleStats Array
* and is capable of sorting them by name and by popularity percentage
*/
BabyNames::BabyNames(const char fn[], const int numLines) {
people = new PeoplStats[MAX_DATA_SIZE]; //edit I put this in but I still get errors
//set current capacity
capacity = numLines;
//Open File
ifstream myfile;
myfile.open(fn);
//read in data
int current = 0;
while (current < capacity) {
myfile >> people[current].year;
myfile >> people[current].name;
myfile >> people[current].percent;
string sex;
myfile >> sex;
people[current].sex = parseSex(sex);
current++;
}
}
BabyNames::~BabyNames(){
cout << "Deconstructor" << endl;
delete[]people; //Edit: I added this
}
/*
* sortByName - Sorts the entire array of people by name using the bubble
* sort algorithm. Array is sorted according to name, within the structure
* Algorithm becomes extremely slow if capacity > 3000
*/
void BabyNames::sortByName(){
//sorted is set to true if no changes were made
bool sorted = false;
//change tells the loop if we made a swap or not
bool change = false;
while (!sorted) {
for (int i = 0; i < capacity - 1; i++) {
int compare = people[i].name.compare(people[i + 1].name);
if (compare == 1) {
swap(i);
change = true;
}
}
//if the array was not changed,
//changed sorted to true and exit loop
if (change == false)
sorted = true;
//otherwise reset change and repeat the loop
else
change = false;
}
}
/**
* sortByPopularity - sorts the entire array using the bubble sort algorithm
* Method is almost exactly the same as sortByName, except the compare
* variable is a double consisting of the difference of the two popularity
* percentages.
* Algorithm becomes extremely slow if capacity > 3000
*/
void BabyNames::sortByPopularity(){
bool sorted = false;
bool change = false;
while (!sorted) {
for (int i = 0; i < capacity - 1; i++) {
double compare = people[i].percent - people[i + 1].percent;
if (compare < 0) {
swap(i);
change = true;
break;
}
}
if (change == false)
sorted = true;
change = false;
}
}
/**
* swap - swaps the positions of people[i] and people[i + 1]
* @param i - index of the people array that will get swapped with i + 1
*/
void BabyNames::swap(int i) {
PeopleStats temp = people[i + 1];
people[i + 1] = people[i];
people[i] = temp;
}
/**
* parseSex: extracts the gender from the input and returns the appropriate enum
* @param s
* @return gender object
*/
gender BabyNames::parseSex(string s) {
if (s == "boy")
return boy;
else if (s == "girl")
return girl;
else
throw "invalid Gender";
}
/**
* getCapacity: returns the number of data entries stored.
* @return size of the data
*/
const int BabyNames::getCapacity(){
return capacity;
}
/**
* get: returns one PeopleStat Object
* @param i
* @require: i < capacity
* @return PeopleStat object
*/
const PeopleStats& BabyNames::get(int i) const {
if (i>=0 && i < capacity)
return people[i];
throw OUT_OF_BOUNDS;
}
/**
* << - overloads the outstream operator for PeopleStats object
* @param os
* @param d
* @return os : output stream
*/
std::ostream & operator << (std::ostream& os, const PeopleStats& d){
os << d.name << " " << d.year << " " << d.percent << " " << d.sex;
return os;
}
/**
* <<: overloads the outstream operator for the BabyNames object
* @param os
* @param bn
* @return
*/
std::ostream& operator<<(std::ostream& os, const BabyNames& bn) {
os << " BabyNames object " << std::endl;
for (int i=0; i < 5000; i++ )
os << " " << (i+1) <<": " << bn.get( i ) << std::endl;
return os;
}//end of operator
Вот основной
/*Title: CS 237 Assignment#1
* Created:
* Feb 27, 2013
* Modified:
* March 1st 2013
********************************/
#include <iostream>
#include "BabyNames.h"
/**
* main: The client function that controls the server, BabyNames
* For reasons currently unknown, the program will take forever
* to run after the * 3000-5000 line mark.
* @return 0 if successful
*/
int main(void) {
cout << "People names: " << endl;
BabyNames names("src/people.txt", 5000 );
cout << names;
cout << "Sorted by popularity" << endl;
names.sortByPopularity();
cout << names;
// cout << "Sorted by name" << endl;
// names.sortByName();
// cout << names;
cout << "... done!" << endl;
return 0;//This is a suggested Main by my professor
/* cout << "People names: " << endl;
const char filename[] = "src/people.txt";
cout << " 1. Reading file: \"" << filename << "\" ... ";
int number_of_names = checklines( filename );
cout << " number of lines in file is: " << number_of_names;
BabyNames* names = new BabyNames( number_of_names );
// read the contents of a file into names and print them
ifstream file( filename, ios::in );
file >> *names;
cout << " file has been read!" << endl;
// Sort and print
cout << " 2. Sorted by popularity:" << endl;
BabyNames* namesByPop = new BabyNames( *names );
namesByPop->sortByPopularity();
cout << *namesByPop;
// Sort and print
cout << " 3. Sorted by name:" << endl;
BabyNames* namesByName = new BabyNames( *names );
namesByName->sortByName();
cout << *namesByName;
// Sort and print
cout << " 4. Sorted by year:" << endl;
BabyNames* namesByYear = new BabyNames( *names );
namesByYear->sortByYear();
cout << *namesByYear;
cout << " 5. Original names:" << endl;
cout << *names;
delete names;
delete namesByYear;
delete namesByName;
delete namesByPop;*/cout << "... all done!" << endl;
}
Кроме того, файл, который я читаю, имеет много строк, которые выглядят так
1880 John 0.081541 boy
1880 William 0.080511 boy
1880 James 0.050057 boy
1880 Charles 0.045167 boy
Я не думаю, что вижу, где вы на самом деле распределяете память в своем конструкторе.
BabyNames::BabyNames(const char fn[], const int numLines) {
people = new PeopleStats[numLines];
// check for null
.....
}
Также освободите память в своем деструкторе:
BabyNames::~BabyNames() {
delete [] people;
}
Я предполагаю, что у вас есть проблемы со следующей строкой в заголовке:
PeopleStats* people = new PeopleStats[MAX_DATA_SIZE];
Вы не можете динамически распределять память в заголовке. Вот почему это не скомпилируется. Вам нужно будет динамически распределять память в файле cpp. Вам просто нужно объявить указатель в заголовке (как вы уже сделали). Затем в конструкторе для класса выделите память, прежде чем пытаться получить к ней доступ.
Заголовок:
class BabyNames {
public:
BabyNames(const char fn[], const int numLines);
~BabyNames();
private:
PeopleStats* people;
};
файл cpp:
BabyNames::BabyNames(const char fn[], const int numLines) {
// dynamicall allocate array
people = new PeopleStats[numLines];
// fill in people array here
}
~BabyNames::BabyNames {
// don't forget to free array or you will have a memory leak
delete [] people;
}