Запись результатов rand () в текстовый файл на C ++ без повторения чисел

0

В этот момент в моей программе я пишу каждый раз, когда генерируется случайное число, содержимое этого числа в массиве записывается в текстовый файл. Код:

#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 first name: ";
    cin >> bar.nameFirst;
    cout << "Type in that student 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();
        }
    }
}

Когда я компилирую, я получаю следующие ошибки:

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

Как устранить эти проблемы (как на линии 181), так и убедиться, что число не генерируется более одного раза?

Теги:
random
ofstream

3 ответа

3
Лучший ответ

std::ofstream не может быть скопирован. Похоже, вам нужна ссылка:

void generateGroups(int numberOfGroups, int maxStudents, 
                    int studentsPerGroup, int remainder, 
                    student theStudents[], int studentsBeenAssigned, 
                    ofstream& studentGroups)
{//                         ^
  • 0
    Это устранило ошибку IntelliSense, но у меня все еще есть первая, о которой я упомянул.
  • 0
    @ DJHead-On Эти сообщения связаны с одной и той же ошибкой.
Показать ещё 3 комментария
3

Вы передаете поток по значению функции generateGroups() что приводит к вызову конструктора копии. Стандартные потоки не могут быть скопированы.

Что касается второй части вашего вопроса, вы не можете ожидать, что PRNG всегда будет возвращать уникальные номера, не говоря уже о том, что вы ограничиваете диапазон модулем. Вам нужно будет написать немного больше кода, который бы проверял, был ли уже у вас уже получен номер, или, другими словами, кто-то уже назначен.

  • 0
    размещение в качестве ответа, ссылка не работает.
  • 0
    Я знаю, что мне нужно написать условное утверждение, но я недостаточно знаком с PRNG, чтобы знать, что кодировать для проверки на наличие дубликатов.
1

Семя, используемое rand(), не будет повторяться до 2 ^ 32 циклов или более для большинства реализаций, но (seed >> xx)% n будет повторяться по крайней мере каждые n циклов и чаще, если n не является взаимно простым с числами используемый линейным конгруэнтным генератором, используемым rand().

Вы можете создать массив из n байтов и использовать их для отслеживания дублирования.

  • 0
    Как мне написать такой массив?
  • 0
    Предположим, вы называете массив num, инициализируете num [] нулем, каждый раз, когда вы получаете число от rand, например, j = rand (), затем устанавливаете k = num [j] и num [j] = 1. Если k == 0, j это новое число, в противном случае j это повторное число. Обратите внимание, что RAND_MAX обычно равен 32767, если вы хотите больший диапазон, создайте свою собственную функцию, подобную ранду, на основе одного из линейных конгруэнтных генераторов из синей ссылки в моем ответе.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню