c++ - 需要范围、运算符、函数错误帮助

标签 c++ scope operators

我对这个程序有一些疑问。我会先快速解释一下它的作用。它从如下所示的文件中读取名称和统计信息:

1880 John 0.081541 boy
1880 William 0.080511 boy
1880 James 0.050057 boy
1880 Charles 0.045167 boy
1904 Zola 0.000157 girl
1904 Juana 0.000154 girl
1904 Ramona 0.000154 girl
1904 Carmella 0.00015 girl

我要读取它并将其存储在一个动态数组中,并能够使用方法进行组织。我的问题是: 1)我的提取操作符有什么问题?为什么它看不到 people 数组?我应该在那里打开文件吗? 2) 为什么我的 main 看不到 checkLines 函数?我不认为它应该是一个成员函数,我认为它应该是独立的。 3)我的复制构造函数有什么问题?有一条黄线而不是一条红线,错误如下:

Multiple markers at this line
    - Member 'capacity' was not initialized in this 
     constructor
    - Member 'people' was not initialized in this 
     constructor
    - Member 'fillCount' was not initialized in this 
     constructor

这是代码

宝宝名字.h

#ifndef BABYNAMES_H_
#define BABYNAMES_H_
#include <string>
#include <fstream>
using namespace std;


/**
 * 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:
    int checklines(const char fn[]);
    BabyNames(BabyNames& people);
    BabyNames(const char fn[], const int numLines);
    ~BabyNames();
    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
    void sortByYear();
    friend std::ostream& operator << (std::ostream& os, const PeopleStats& d);
    friend std::ostream& operator << (std::ostream& os, const BabyNames& bn);
    friend std::istream& operator >> (std::istream& in, PeopleStats& ac);
    friend std::istream& operator >> (std::istream& in, BabyNames& ac);
     //int filled; //keeps track of how many array locations have data objects

private:
    static const int MAX_DATA_SIZE = 2000;
    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 */

宝宝名字.cpp

#include <iostream>
#include <string>
#include <fstream>
using namespace std;
#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 PeopleStats[numLines];
    capacity = numLines;    //set current capacity
    ifstream myfile;        //Open File
    myfile.open(fn);        //read in data
    int filled = 0;
    while (filled < capacity) {
        myfile >> people[filled].year;
        myfile >> people[filled].name;
        myfile >> people[filled].percent;
        string sex;
        myfile >> sex;
        people[filled].sex = parseSex(sex);
        filled++;
    }

}

//Copy Constructor
BabyNames::BabyNames(BabyNames& people){
    PeopleStats* copyPeople = new PeopleStats[];
    for (int i=0; i<500 ;i++)
        copyPeople[i] = people[i];
}

PeopleStats& operator =(const PeopleStats& people){
    PeopleStats x = new PeopleStats[2000];
    for (int i=0; i<2000 ;i++)
        x[i] = people[i];
    return *this;
}//make a member with one parameter


std::istream& operator >> (std::istream& in, PeopleStats& ac){
string str;
ifstream myfile;        //Open File
    myfile.open(fn);        //read in data
    int filled = 0;
myfile >> people[filled].year;
        myfile >> people[filled].name;
        myfile >> people[filled].percent;
        string sex;
        myfile >> sex;
        people[filled].sex = parseSex(sex);
        filled++;
        }
    }//struct doesnt need a loop in the operator
    return in;
}

std::istream& operator >> (std::istream& in, BabyNames& ac){
string str;

    while (in >> str){
        string strInput;
        getline(inf, strInput);
        in >> strInput;

    }//struct doesnt need a loop in the operator
    return in;
}
//Baby names extraction operator does need a loop

int checkLines(const char fn[]){
    int number_of_lines = 0;
    std::string line;
    ifstream myfile("textexample.txt");
    while (std::getline(myfile, line))
        ++number_of_lines;
    std::cout << "Number of lines in text file: " << number_of_lines;
    return number_of_lines;
}//make a stand alone function



BabyNames::~BabyNames(){
    cout << "Destructor to deallocate memory... Done!" << endl;
    delete[]people;
}


/*
 * 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;
    }
}

void BabyNames::sortByYear(){
    bool sorted = false;
    bool change = false;
    while (!sorted) {
        for (int i = 0; i < capacity - 1; i++) {
            double compare = people[i].year - people[i + 1].year;
            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;
}
/**     string strInput;
        getline(inf, strInput);
        in >> strInput;
 * 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 < 2000; i++ )
        os << "    " << (i+1) <<":  " << bn.get( i ) << std::endl;
    return os;
}//end of operator

主要

#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", 2000);
    cout << names;

    cout << "Sorted by popularity" << endl;
    names.sortByPopularity();
    cout << names;
//    cout << "Sorted by name" << endl;
//    names.sortByName();
//    cout << names;
        cout << "Sorted by year" << endl;
        names.sortByYear();
        cout << names;
    cout << "... done!" << endl;
    return 0;*/

    cout << "Baby 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: " << "2000";
    BabyNames* names = new BabyNames( "src/people.txt", 2000 );

    // 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;
}

最佳答案

1)因为你的提取算子不是类的成员。你需要 ac.people。您绝对不应该在提取操作符中打开文件,打开的文件(或其他文件)是通过 in 参数传入的。

2) 因为您还没有告诉 main(即您没有在 main 可以看到的任何地方定义它)。也许最简单的方法是在 BabyNames.h 的底部附近添加 int checkLines(const char fn[]);

3) 你的拷贝构造函数有问题。一方面,它不会初始化您正在构造的对象,而只是创建一个名为 copyPeople 的数组,然后将其丢弃,而您正在构造的对象完全保持不变。另一个问题是参数应该声明为 const。这样的东西会更好

//Copy Constructor
BabyNames::BabyNames(const BabyNames& bn){
    people = new PeopleStats[bn.capacity];
    for (int i=0; i<bn.capacity ;i++)
        people[i] = bn.people[i];
    capacity = bn.capacity;
    fillCount = bn.fillCount;
}

出于类似的原因,您的赋值运算符也是错误的。

关于c++ - 需要范围、运算符、函数错误帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15573403/

相关文章:

c - 在两个增量和间接运算符的情况下,C 如何处理运算优先级?

c# - C# 中具有可空类型的 += 运算符

C++ delete[] 运算符

c++ - 这段关于 scanf 的代码是什么?

java - 在 Java 中仅在堆上创建对象的优缺点是什么?

c++ - 我需要通过我的函数传递什么样的参数。另外,如何让它根据用户需要循环多次?

java - 什么是无作用域 bean 以及何时使用它?

java - 如何将变量从 Main Activity 传递到 AsyncTask 及其方法?

MySql REGEXP 运算符

c++ - 将特征向量转换为 QString 进行显示