Question

At this point in my program, I am writing for every time a random number is generated, the contents of that number in an array is written to a text file. The code:

#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <time.h>
#include "inFrench.h"

using namespace std;

class student
{
    int m_studentNumber;
public:
    string nameFirst;
    string nameLast;
    string nameFull;
    int getStudentNumber() { return m_studentNumber; }
    void setStudentNumber(int studentNumber) { m_studentNumber = studentNumber; }
};

ostream& operator<<(ostream& os, const student& s)
{
    return os << s.nameFirst << ' ' << s.nameLast;
}

student typeName()
{
    student bar;
    cout << "Type in a student's first name: ";
    cin >> bar.nameFirst;
    cout << "Type in that student's last name: ";
    cin >> bar.nameLast;
    bar.nameFull = bar.nameFirst + " " + bar.nameLast;
    return bar;
}

void displayStudents(student listOfStudents[50], int studentHeadCount)
{
    for (int i = 0; i < studentHeadCount; i++)
    {
        cout << listOfStudents[i].nameFull << endl;
        cout << listOfStudents[i].getStudentNumber() << endl;
        cout << "\n";
    }
}

void generateGroups(int numberOfGroups, int maxStudents, int studentsPerGroup, int remainder, student theStudents[], int studentsBeenAssigned, ofstream studentGroups)
{
    int k;
    numberOfGroups = maxStudents / studentsPerGroup;
    cout << numberOfGroups << endl;
    srand(time(NULL));
    studentGroups.open("studentGroups.txt");
    while (studentsBeenAssigned < maxStudents && studentsBeenAssigned < maxStudents - remainder)
    {
        for (int j = 0; j < maxStudents - remainder; j++)
        {
            k = rand() % maxStudents;
            cout << theStudents[k].nameFull << endl;
            studentGroups << theStudents[k].nameFull << endl;
            studentsBeenAssigned++;
            if (studentsBeenAssigned == studentsPerGroup)
            {
                cout << "\n";
                studentGroups << theStudents[k].nameFull << endl;
                studentsBeenAssigned = 0;
            }
        }
    }
    if (remainder < studentsPerGroup && remainder > 0)
    {
        for (int l = 0; l < remainder; l++)
        {
            cout << theStudents[k].nameFull << endl;
        }   
    }
}

void languageChoices()
{
    cout << "Select your language from the following:\n";
    cout << "a) English\n";
    cout << "b) French\n";
    cout << "\n";
}

void options()
{

    cout << "Select what you want to do:\n";
    cout << "1) Exit application\n";
    cout << "2) Enter a Student\n";
    cout << "3) Display Students\n";
    cout << "4) Display Groups\n";
    cout << "5) Output groups as text file\n";
    cout << "6) Reset number of students in class\n";
    cout << "7) Reset number of students per group\n";
    cout << "\n";
}

int main()
{
    char selectedLanguage;
    languageChoices();
    cin >> selectedLanguage;
    switch (selectedLanguage)
    {
        case 'a':
        {
            student allStudents[50]; // Having 50 students alone is ridiculous!
            bool endProg = 0;
            int maxStudents;
            int studentsPerGroup;
            int optionSelect;
            int studentHeadCount = 0;
            int remainder = 0;
            int numberOfGroups = 0;
            int studentsBeenAssigned = 0;
            ofstream studentGroups;
            cout << "GroupPicker 1.0\n";
            cout << "Note: This version of the program is intended for purposes of education only, " 
            << "specifically for teacher use in a classroom.\n\n";
            cout << "How many students are in the class?\n" << "(Note: You cannot have more than 50 in this program)\n";
            cin >> maxStudents;
            if (maxStudents > 50)
            {
                cerr << "Too many students!\n" << "Exiting program...\n";
                system("PAUSE");
                exit(1);
            }
            if (maxStudents >= 35 && maxStudents <= 50)
            {
                cout << maxStudents << " students? You are a pro!\n";
            }
            cout << "How many students per group?\n";
            cin >> studentsPerGroup;
            if (studentsPerGroup >= maxStudents || studentsPerGroup <= 1)
            {
                cerr << "You're kidding, right?\n" << "Exiting program...\n";
                system("PAUSE");
                exit(1);
            }
            while (endProg == 0) {
                options();
                cin >> optionSelect;
                switch (optionSelect) {
                    case 1:
                        endProg = 1;
                        break;
                    case 2:
                    {
                        if (studentHeadCount == maxStudents)
                        {
                            cerr << "You can't enter more than " << maxStudents << " students\n";
                        }
                        else
                        {
                            allStudents[studentHeadCount] = typeName();
                            allStudents[studentHeadCount].setStudentNumber(studentHeadCount);
                            cout << "Student (" << allStudents[studentHeadCount].nameFull << ") entered.\n";
                            cout << "\n";
                            studentHeadCount++;
                        }
                        break;
                    }
                    case 3:
                        cout << "Current list of students:\n\n";
                        displayStudents(allStudents, studentHeadCount);
                        break;
                    case 4:
                    {
                        if (studentHeadCount < studentsPerGroup || studentHeadCount < maxStudents)
                        {
                            cerr << "Invalid group parameters.\n" << "Returning to main menu...\n\n";
                            break;
                        }
                        else
                        {
                            cout << "Here are the groups:\n\n";
                            studentGroups.open("studentGroups.txt");
                            generateGroups(numberOfGroups, maxStudents, studentsPerGroup, remainder, allStudents, studentsBeenAssigned, studentGroups);
                        }
                        break;
                    }
                    case 5:
                    {
                        cout << "Saving groups to file...\n";
                        studentGroups.close();
                        break;
                    }
                    case 6:
                    {
                        cout << "How many students are in the class?\n" << "(Note: You cannot have more than 50 in this program)\n";
                        cin >> maxStudents;
                        if (maxStudents > 50)
                        {
                            cerr << "Too many students!\n" << "Try again...\n";
                        }
                        if (maxStudents >= 35 && maxStudents <= 50)
                        {
                            cout << maxStudents << " students? You are a pro!\n";
                        }
                        break;
                    }
                    case 7:
                    {
                        cout << "How many students per group?\n";
                        cin >> studentsPerGroup;
                        if (studentsPerGroup >= maxStudents || studentsPerGroup <= 1)
                        {
                            cerr << "You're kidding, right?\n" << "Try again...\n";
                        }
                        break;
                    }
                }
            }
            break;
        }
        case 'b':
        {
            mainInFrench();
        }
    }
}

When I compile, I get the following errors:

error C2248: 'std::basic_ofstream<_Elem,_Traits>::basic_ofstream' : cannot access private member declared in class 'std::basic_ofstream<_Elem,_Traits>'
IntelliSense: "std::basic_ofstream<_Elem, _Traits>::basic_ofstream(const std::basic_ofstream<_Elem, _Traits>::_Myt &_Right) [with _Elem=char, _Traits=std::char_traits<char>]" (declared at line 1034 of "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\fstream") is inaccessible

How do I resolve these issues (Both on Line 181) and make sure that no number is generated more than once?

Was it helpful?

Solution

std::ofstream cannot be copied. It looks like you need a reference:

void generateGroups(int numberOfGroups, int maxStudents, 
                    int studentsPerGroup, int remainder, 
                    student theStudents[], int studentsBeenAssigned, 
                    ofstream& studentGroups)
{//                         ^

OTHER TIPS

You are passing stream by value to generateGroups() function which results in copy constructor call. Standard streams cannot be copied.

As for the second part of your question, you cannot expect PRNG to always return unique numbers, let alone when you limit the range with modulus. You'll need to write a bit more code which would check if the number you've got was already generated before, or in other words that some student has already been assigned.

The seed used by rand() won't repeat until 2^32 cycles or more on most implementations, but (seed>>xx)%n will repeat at least every n cycles and more frequently if n is not relatively prime to the numbers used by the linear congruential generator used by rand().

You could make an array of n bytes and use them to track if there's been a duplicate.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top