coversion to java

/*******************************************************************************
Files: testbank.txt - Sequential Access - Input &
Output - - Storage of all questions
*******************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include

// Maximum number of questions that can be stored in
the array
const int iMAX_QUESTIONS = 10;
const int iMENU_ITEMS = 8;

// File names
const char cTESTBANK_FILE_NAME [] = "testbank.txt";

// First line of all output
const char cMAIN_HEADING[] = "TEST BANK MAINTENANCE
SYSTEM";

// Screen Subheadings and other messages
const char cADD_QUESTION_HEADING[] = "*** ADD QUESTION
***",
cQUESTION_ADDED_MESSAGE[] = "QUESTION ADDED",
cMODIFY_QUESTION_HEADING[] = "*** MODIFY QUESTION
***",
cQUESTION_MODIFIED_MESSAGE[] = "QUESTION MODIFIED",
cQUESTION_NOT_MODIFIED_MESSAGE[] = "QUESTION NOT
MODIFIED",
cDELETE_QUESTION_HEADING[] = "*** DELETE QUESTION
***",
cQUESTION_DELETED_MESSAGE[] = "QUESTION DELETED",
cQUESTION_NOT_DELETED_MESSAGE[] = "QUESTION NOT
DELETED",
cGENERATE_QUESTIONS_HEADING[] = "*** GENERATE QUESTION
SET ***",
cQUESTIONS_GENERATED_MESSAGE[] = "QUESTIONS
GENERATED",
cGENERATED_QUESTIONS_HEADING [] = "*** GENERATED
QUESTIONS ***",
cANY_KEY_MSG[] = "PRESS ANY KEY TO CONTINUE",
cGOODBYE_MESSAGE[] = "THANK YOU FOR USING THE TEST
BANK SYSTEM";

// Menu array
const char *cMENU[iMENU_ITEMS] = {" *** MAIN MENU
***",
"Please select an option:",
"a. Add question",
"b. Modify question",
"c. Delete question",
"d. Generate question set",
"x. Exit",
"Option? "};

// menu options
const char cEXIT_OPTION = 'X',
cNEW_QUESTION_OPTION = 'A',
cMODIFY_QUESTION_OPTION = 'B',
cDELETE_QUESTION_OPTION = 'C',
cGENERATE_QUESTIONS_OPTION = 'D';

// Used to test for mandatory and optional input
fields
const char cMANDATORY = 'M';
const char cOPTIONAL = 'O';

// Screen positioning - columns
const int iLEFT_MARGIN = 5;
const int iCOL_POS = 30;

// Screen positioning - rows
const int iHEADING_LINE = 2;
const int iERROR_LINE = 20;
const int iEND_LINE = 22;

const int iQUESTION_NUMBER_LINE = iHEADING_LINE + 4;
const int iQUESTION_LINE = iHEADING_LINE + 6;
const int iANSWER_LINE = iHEADING_LINE + 8;
const int iDIFFICULTY_LEVEL_LINE = iHEADING_LINE + 10;
const int iOPTION_LINE = iHEADING_LINE + 12;
const int iDELETEMODIFY_QUESTION_LINE = iHEADING_LINE
+ 14;

// Validation strings
const char cANSWERS[] = "TF";
const char cVALID_MENU_OPTIONS[]="ABCDX";
const char cVALID_RESPONSE_LIST[] = "YN";

// Input field maximum lengths
const int iQUESTION_LEN = 150;

// error messages
const char cERR_MENU[] = "ERROR - Menu option must be
";
const char cERR_ARRAY_MAX_MSG[]
= "ERROR - Maximum number of questions reached. Unable
to add more.";
const char cERR_FILE_OPEN_MSG[] = "ERROR - Unable to
open file: ";
const char cERR_NO_QUESTIONS_MSG[]
= "ERROR - No questions yet recorded. Unable to
fulfill your request";
const char cERR_MANDATORY_MSG[] = "ERROR - Mandatory
field. Please enter";
const char cERR_ANSWER[] = "ERROR - Answer must be ";
const char cERR_INVALID_YN_RESPONSE[] = "ERROR -
Response must be ";
const char cERR_INVALID_DIFFICULTY[] = "ERROR! -
Difficulty Level must be between ";
const char cERR_INVALID_QUESTION_NUMBER[] = "ERROR! -
Question Number must be between ";
const char cERR_ALREADY_DELETED[] = "ERROR! - This
question has been deleted.";
const char cERR_NO_QUESTIONS[] = "ERROR! - No
available questions to generate.";
const char cERR_INVALID_NUM_OF_QUESTIONS[] = "ERROR! -
Number of questions must be between ";

// enumerated difficulty levels
const enum {EASY = 1, MEDIUM, DIFFICULT};
// enumerated question status
const enum {INITIAL = -1, ACTIVE, DELETED};

// date format
struct stDate
{
int iDay;
int iMonth;
int iYear;
};

// question record format
struct stQuestion
{
int iQuestionNumber;
char cQuestion[iQUESTION_LEN];
char cAnswer;
int iDifficultyLevel;
int iStatus;
};

stQuestion stAddNewquestion(int iNewQuestionNumber);
void vInitialiseQuestions(stQuestion
stQuestionArray[], int iArraySize);
stQuestion stReadQuestionRecord (ifstream
&questionFile);
int iReadQuestionFile(stQuestion stQuestionArray[]);
void vInputString ( int iLineNum, char cInput[],
const int iInputLength, char cMand);
void vDisplayTemplate(const char cHeading[]);
char cMenu(bool bIfInitial = false, int iNumQuestions
= 0);
char cInputLetter (int iLineNum, const char
cValidList[],
const char cErrorMsg[], char cMand);
stDate dtInputBirthDate ();
bool bValidateDate(char cTemp[], stDate &dtInputDate);
char cValidateLetter(int iPromptLine, char
cValidList[]);
int iValidateIntRange(int iMin, int iMax, const char
cErrorMsg[],
int iLineNum, char cMand);
bool bValidateString (char cTemp[], const char
cValidList[],
const char cErrorMsg[]);
void vDisplayRecord(stQuestion stQuestionRecord);
void vModifyQuestion(stQuestion stQuestionArray[]);
void vDeleteQuestion(stQuestion stQuestionArray[]);
void vGenerateQuestions(stQuestion stQuestionArray[],
int iNumQuestions);
int *vRandomlyGenerateNumbers(int
iNumbersToGenerate,int iMaximumQuestions,
stQuestion stQuestionArray[]);
void vDisplayGeneratedQuestions(int
*iGeneratedQuestions,
int iNumGeneratedQuestions,
stQuestion stQuestionArray[]);
void vHeadings();
int vWriteFile (stQuestion stQuestionArray[], int
iNumQuestions);
void vOutputArray(stQuestion stQuestionArray[], int
iArraySize);
void vPause();
int iDetermineLastActiveQuestionNum(stQuestion
stQuestionArray[], int iArraySize);

void main()
{
// array used to store all conatct information
stQuestion stQuestionArray[iMAX_QUESTIONS];

// initialise questions to null
vInitialiseQuestions(stQuestionArray, iMAX_QUESTIONS);

// count of the number of questions in the array. The
first
// value is the number of records read from the file.
int iNumQuestions = 0, iActualNumQuestions = 0;

// the first available i.e. undeleted question index.
int iQuestionIndex;

// user selected menu option
char cOption;

// count of number of questions written to the file at
the end.
int iQuestionsWritten;

// read question file and store all records in the
array
iNumQuestions = iReadQuestionFile(stQuestionArray);

// display the menu
cOption = cMenu(true, iNumQuestions);

// evaluate the entered option
while (cOption != cEXIT_OPTION)
{
if (cOption == cNEW_QUESTION_OPTION)
{
// check if array size will be exceeded
// should more questions be added
if ((iNumQuestions + 1) > iMAX_QUESTIONS)
{
gotoxy (iLEFT_MARGIN, iERROR_LINE);
cout << cERR_ARRAY_MAX_MSG;
}
else
{
// intialise question number to the first available
// empty record
iQuestionIndex = iNumQuestions;
// But in case, a question has been deleted, find the
// first available question number by looking
// for the first deleted questions
for (int i = 0; i< iNumQuestions; i++)
{
if (stQuestionArray[i].iStatus == DELETED)
{
iQuestionIndex = i;
break;
}
}

// input new question information and store in the
array
stQuestionArray[iQuestionIndex] =
stAddNewquestion(iQuestionIndex + 1);
iNumQuestions++;
}
}
else
{
if (iNumQuestions < 1)
{
gotoxy (iLEFT_MARGIN, iERROR_LINE);
cout << cERR_NO_QUESTIONS_MSG;
}
else
{
switch (cOption)
{
case cMODIFY_QUESTION_OPTION:
// modify selected questions
vModifyQuestion(stQuestionArray);
break;
case cDELETE_QUESTION_OPTION:
// delete selected question
vDeleteQuestion(stQuestionArray);
iNumQuestions--;
break;
case cGENERATE_QUESTIONS_OPTION:
// display all questions directing the output to a
file
vGenerateQuestions(stQuestionArray, iNumQuestions);
break;
}
}

}
// vOutputArray(stQuestionArray, iNumQuestions);
vPause();
// redisplay menu and accept new option
cOption = cMenu();
}

iActualNumQuestions =
iDetermineLastActiveQuestionNum(stQuestionArray,
iMAX_QUESTIONS);
//cout << "Number of questions before writing to file
are:" << iActualNumQuestions << endl;
//getch();
// Write all questions to file before exiting the
program
iQuestionsWritten = vWriteFile (stQuestionArray,
iActualNumQuestions);

// Output number of questions written to file
gotoxy (iCOL_POS, iEND_LINE - 4);
cout << iQuestionsWritten;
if (iQuestionsWritten == 1)
cout << " question ";
else
cout << " questions ";
cout << "saved to file.";

gotoxy (iCOL_POS, iEND_LINE - 2);
cout << cGOODBYE_MESSAGE;

vPause();
}

/*******************************************************************************
Name: vOutputArray
Purpose: To output each record stored in the array.
This function is used for
debugging purposes only.
Pass: Reference to the question array (array of
structs)
Size of array (int)
Return: none
*******************************************************************************/

void vOutputArray(stQuestion stQuestionArray[], int
iArraySize)
{
cout << "Array elements are :

";
for (int i = 0; i < iArraySize; i++)
{
cout << stQuestionArray[i].iQuestionNumber << ". "
<< (stQuestionArray[i].cQuestion) << endl
<< stQuestionArray[i].cAnswer << endl
<< stQuestionArray[i].iDifficultyLevel << endl
<< stQuestionArray[i].iStatus << endl << endl;
}
}

/*******************************************************************************
Name: vInitialiseQuestions
Purpose: To initialise each record stored in the array
with a question number,
empty string for questions, space for answer, and -1
for status.
Pass: Reference to the question array (array of
structs)
Size of array (int)
Return: none
*******************************************************************************/

void vInitialiseQuestions(stQuestion
stQuestionArray[], int iArraySize)
{
for (int i = 0; i < iArraySize; i++)
{
stQuestionArray[i].iQuestionNumber = (i+1);
strcpy(stQuestionArray[i].cQuestion, " ");
stQuestionArray[i].cAnswer = ' ';
stQuestionArray[i].iDifficultyLevel = 0;
stQuestionArray[i].iStatus = INITIAL;
}
}


/*******************************************************************************
Name: iReadquestionFile
Purpose: To read every record on the question file and
store them in an array
Pass: The array into which to place the question
information
Return: A count of the number of records placed in the
array
*******************************************************************************/

int iReadQuestionFile(stQuestion stQuestionArray[])
{
ifstream inQuestionFile;
int iQuestionNum = 0;
stQuestion stQuestionRecord;

// open the question file
inQuestionFile.open(cTESTBANK_FILE_NAME);

// if the file opened OK get the data from it
if (!inQuestionFile)
{
gotoxy (iLEFT_MARGIN, iERROR_LINE);
cout << cERR_FILE_OPEN_MSG;
}
else
{
// read the initial record
stQuestionRecord =
stReadQuestionRecord(inQuestionFile);
// read all records and store into the array
while (!inQuestionFile.eof())
{
// increment and assign question number to record
stQuestionRecord.iQuestionNumber = iQuestionNum + 1;
// copy question record to array
stQuestionArray[iQuestionNum] = stQuestionRecord;
iQuestionNum++;
// this will ignore any characters in the file like

etc
// and wont cause problems with reading the next
record
inQuestionFile.ignore();
// read the next record
stQuestionRecord =
stReadQuestionRecord(inQuestionFile);
}
// close file after reading
inQuestionFile.close();
}

return iQuestionNum;
}

/*******************************************************************************
Name: iReadquestionRecord
Purpose: To read one record from the question file
Pass: Address of the question file
Return: The record read
*******************************************************************************/

stQuestion stReadQuestionRecord (ifstream
&questionFile)
{
stQuestion stQuestionRecord;

questionFile.getline(stQuestionRecord.cQuestion,
iQUESTION_LEN + 1);
questionFile >> stQuestionRecord.cAnswer;
questionFile >> stQuestionRecord.iDifficultyLevel;
stQuestionRecord.iStatus = ACTIVE;

return stQuestionRecord;
}

/*******************************************************************************
Name: cMenu
Purpose: To display the main menu and input and
validate the users selection.
The number of questions read from file is displayed
only if the
menu is initially displayed.
Pass: If this is the intitial display (boolean)
Number of questions read from file (int)
Return: The entered option (char)
*******************************************************************************/

char cMenu(bool bIfInitial, int iNumQuestions)
{
char cOption;

clrscr();
cout << setiosflags(ios::left);
gotoxy (iLEFT_MARGIN, iHEADING_LINE);
cout << ' ' << cMAIN_HEADING << endl << endl;

for (int i = 0; i < iMENU_ITEMS; i++)
{
// output menu items for a constant string
cout << ' ' << cMENU[i];
if ((i == 0) || (i == 1) || (i == (iMENU_ITEMS - 2)))
cout << endl << endl;
else
cout << endl;
}

// only outputs number of questions for the intitial
menu display
if (bIfInitial)
{
gotoxy(iCOL_POS, iEND_LINE - 2);
cout << iNumQuestions;
if (iNumQuestions == 1)
cout << " question ";
else
cout << " questions ";
cout << "in system.";
}

// input and validate option
cOption = cInputLetter(iOPTION_LINE,
cVALID_MENU_OPTIONS, cERR_MENU, cMANDATORY);

return cOption;
}

Comments

  • [b][red]This message was edited by guest001 at 2005-10-7 1:7:53[/red][/b][hr]


    /*******************************************************************************
    Name: cAddNewquestion
    Purpose: To input and validate the question
    information, create a question record
    and append it to the question file.
    Pass: First available question number (int)
    Return: The created question record (struct)
    *******************************************************************************/

    stQuestion stAddNewquestion(int iNewQuestionNumber)
    {
    stQuestion stNewQuestion;

    // display heading and template
    vDisplayTemplate(cADD_QUESTION_HEADING);

    stNewQuestion.iQuestionNumber = iNewQuestionNumber;
    gotoxy(iCOL_POS, iQUESTION_NUMBER_LINE);
    cout << stNewQuestion.iQuestionNumber;

    // input and validate question
    vInputString(iQUESTION_LINE, stNewQuestion.cQuestion,
    iQUESTION_LEN,
    cMANDATORY);

    // input and validate answer
    stNewQuestion.cAnswer = cInputLetter (iANSWER_LINE,
    cANSWERS,
    cERR_ANSWER, cMANDATORY);

    // input and validate difficult level
    stNewQuestion.iDifficultyLevel =
    iValidateIntRange(EASY, DIFFICULT,
    cERR_INVALID_DIFFICULTY, iDIFFICULTY_LEVEL_LINE,
    cOPTIONAL);

    // assign status
    stNewQuestion.iStatus = ACTIVE;

    gotoxy (iCOL_POS, iEND_LINE - 2);
    cout << cQUESTION_ADDED_MESSAGE;

    return stNewQuestion;
    }

    /*******************************************************************************
    Name: vDisplayTemplate
    Purpose: To display the screen for entering or viewing
    a single question
    Pass: The heading to be used for the display (string)
    Return: Nil
    *******************************************************************************/

    void vDisplayTemplate(const char cHeading[])
    {
    clrscr();

    gotoxy (iLEFT_MARGIN, iHEADING_LINE);
    cout << ' ' << cMAIN_HEADING << endl << endl;
    cout << ' ' << cHeading << endl << endl;

    gotoxy (iLEFT_MARGIN, iQUESTION_NUMBER_LINE);
    cout << ' ' << setw(20) << "Question Number: ";
    gotoxy (iLEFT_MARGIN, iQUESTION_LINE);
    cout << ' ' << setw(20) << "Question: ";
    gotoxy (iLEFT_MARGIN, iANSWER_LINE);
    cout << ' ' << setw(20) << "Answer: ";
    gotoxy (iLEFT_MARGIN, iDIFFICULTY_LEVEL_LINE);
    cout << ' ' << setw(20) << "Difficulty Level: ";
    }

    /*******************************************************************************
    Name: vInputString
    Purpose: To input and validate all character string
    input.
    Pass: The screen position of the input (int)
    The string into which the entered data will be placed
    (int)
    The maximum length of the input field (int)
    A character of M or O indicating whether the field is
    mandatory
    or optional (char)
    Return: Nil
    *******************************************************************************/

    void vInputString ( int iLineNum, char cInput[],
    const int iInputLength, char cMand)
    {
    char cTemp[iQUESTION_LEN];
    bool bValid = false;

    while (!bValid)
    {
    // clear cin status
    cin.seekg(0);
    cin.clear();
    // clear any previous input on the input line and the
    line after it
    gotoxy (1, iLineNum + 1);
    clreol();
    gotoxy(iCOL_POS, iLineNum);
    clreol();
    // input string
    cin.getline (cTemp, iQUESTION_LEN);
    // clear previous error messages
    gotoxy (iLEFT_MARGIN, iERROR_LINE);
    clreol();
    // clear previous input
    // gotoxy (iCOL_POS, iLineNum);
    // clreol();
    // `cout << cTemp;
    // discard any characters over maximum permitted
    strncpy (cInput, cTemp, iInputLength-1);
    // ensure character string is null terminated
    cInput[iInputLength-1] = '';
    // validate input, the length must be greater than 0,
    the string
    // must not be empty and the first character must not
    be a space
    if ((strlen(cInput) >= 1) && (strcmpi(cInput, " ") !=
    0)
    && (cInput[0] != ' '))
    {
    bValid = true;
    }
    // if the input is optional, assign an empty string to
    it
    else if (cMand == cOPTIONAL)
    {
    bValid = true;
    strcpy (cInput, " ");
    }
    else
    {
    gotoxy (iLEFT_MARGIN, iERROR_LINE);
    cout << cERR_MANDATORY_MSG;
    }
    }
    }

    /**************************************************************************
    Name: iValidateIntRange
    Purpose: To input and validate an integer input by the
    user that should
    be within an inclusive range of minimum and maximum
    value
    Pass: The minimum value for range (int)
    The maximum values of the valid range (int)
    The error message to be output (string)
    Line number for output (int)
    Whether or not the input is mandatory (char)
    Return: Validated integer
    *******************************************************************************/

    int iValidateIntRange(int iMin, int iMax,
    const char cErrorMsg[], int iLineNum, char cMand)
    {
    const int iINPUT_LEN = 50;
    int iNum;

    char cTemp[iINPUT_LEN], cInput[iINPUT_LEN];
    char cError_msg[100];
    bool bValid = false;

    // generate error message string
    strcpy(cError_msg, cErrorMsg);
    itoa(iMin, cTemp, 10);
    strcat(cError_msg, cTemp);
    strcat(cError_msg, " and ");
    itoa(iMax, cTemp, 10);
    strcat(cError_msg, cTemp);
    strcat(cError_msg, " inclusive.");

    while (!bValid)
    {
    gotoxy (iCOL_POS, iLineNum);
    clreol();
    // clear cin status
    cin.seekg(0);
    cin.clear();
    // accept input
    gotoxy (iCOL_POS, iLineNum);
    cin.getline (cInput, 50);
    // clear previous error messages
    gotoxy (iLEFT_MARGIN, iERROR_LINE);
    clreol();
    bValid = true;

    // validate input, if any
    // if the input is mandatory and if its length is 0
    // or if the first character is just a space
    if ((cMand == cMANDATORY) && ((strlen(cInput) < 1)
    || (cInput[0] == ' ')))
    {
    cout << cERR_MANDATORY_MSG;
    bValid = false;
    }
    // if input is optional, just set the value of input
    to 0
    else if ((cMand == cOPTIONAL) && (strlen(cInput) < 1))
    {
    bValid = true;
    iNum = 1;
    }
    else
    // range validation by converting string to integer
    first
    {
    iNum = atoi(cInput);
    if ((iNum < iMin) || (iNum > iMax))
    {
    cout << cError_msg;
    bValid = false;
    }
    }
    }

    return iNum;
    }


    /*******************************************************************************
    Name: bValidateString
    Purpose: To validate a passed string against another
    string of acceptable
    characters.
    Pass: The string to be validated and
    the string containing all acceptable characters
    Return: true if the string is valid, false if it
    contains invalid characters.
    *******************************************************************************/
    bool bValidateString (char cTemp[], const char
    cValidList[],
    const char cErrorMsg[])
    {
    bool bValid = true;
    strupr(cTemp);

    for (int i = 0; i<strlen(cTemp); i++)
    {
    if (strchr (cValidList, cTemp[i]) == '')
    {
    bValid = false;
    gotoxy (iLEFT_MARGIN, iERROR_LINE);
    cout << cErrorMsg;
    break;
    }
    }

    return bValid;
    }
    /*******************************************************************************
    Name: cInputLetter
    Purpose: To input and validate a character input.
    Pass: The screen position of the input;
    A character array of permissible characters, against
    which the input is validated;
    The error message
    A character of M or O indicating whether the field is
    mandatory or optional.
    Return: The valid character
    *******************************************************************************/
    char cInputLetter (int iLineNum, const char
    cValidList[],
    const char cErrorMsg[], char cMand)
    {
    char cInput;

    bool bValid = false;

    while (!bValid)
    {
    // clear cin status
    cin.seekg(0);
    cin.clear();
    // accept input
    gotoxy (iCOL_POS, iLineNum);
    clreol();
    cin.get (cInput);
    // clear previous error messages
    gotoxy (iLEFT_MARGIN, iERROR_LINE);
    clreol();
    // clear previous input
    gotoxy (iCOL_POS, iLineNum);
    clreol();
    cout << cInput;

    // validate input, if any
    if (cInput != '
    ' && cInput != ' ')
    {
    // convert input to upper case for comparison
    cInput = toupper(cInput);

    // find if input is in the list of valid charcaters
    for (int i=0; i<strlen(cValidList); i++)
    {
    if (cInput == cValidList[i])
    {
    bValid = true;
    }
    }
    if (!bValid)
    {
    gotoxy (iLEFT_MARGIN, iERROR_LINE);
    cout << cErrorMsg;
    for (int i=0; i < (strlen(cValidList)- 1); i++)
    {
    cout << cValidList[i] << " ";
    }
    cout << "or " << cValidList[strlen(cValidList)-1];
    }
    }
    // no input - error if letter was mandatory
    else if (cMand == cMANDATORY)
    {
    gotoxy (iLEFT_MARGIN, iERROR_LINE);
    cout << cERR_MANDATORY_MSG;
    }
    // no input - OK if optional
    else
    {
    bValid = true;
    }
    }
    return cInput;
    }

    /******************************************************************************
    Name: iDetermineLastActiveQuestionNum
    Purpose: Finds the first question that is both
    inactive and not deleted,
    i.e. has a status of -1. This can be used for the
    maximum number of
    elements to traverse in the array
    Pass: Reference to questions array (array of structs)
    Size of array (int)
    Return: Last Active Question Number (i.e. the first
    unoccupied question index)
    *******************************************************************************/
    int iDetermineLastActiveQuestionNum(stQuestion
    stQuestionArray[], int iArraySize)
    {
    int iLastActiveQuestionNum;

    for (int i=0; i<iArraySize; i++)
    {
    if (stQuestionArray[i].iStatus == -1)
    {
    iLastActiveQuestionNum = i;
    break;
    }
    }
    return iLastActiveQuestionNum;
    }

    /******************************************************************************
    Name: vModifyQuestion
    Purpose: To modify a question as requested by user.
    Pass: Reference to questions array (array of structs)
    Number of questions (int)
    Return: None
    *******************************************************************************/
    void vModifyQuestion(stQuestion stQuestionArray[])
    {
    int iModifyQuestionNum;

    char cResponse;
    int iLastActiveQuestionNum = 0;

    stQuestion stModifyQuestion;

    // display heading and template
    vDisplayTemplate(cMODIFY_QUESTION_HEADING);

    // determine last active questions
    iLastActiveQuestionNum =
    iDetermineLastActiveQuestionNum
    (stQuestionArray, iMAX_QUESTIONS);

    iModifyQuestionNum = iValidateIntRange(1,
    iLastActiveQuestionNum,
    cERR_INVALID_QUESTION_NUMBER, iQUESTION_NUMBER_LINE,
    cMANDATORY);

    stModifyQuestion = stQuestionArray[iModifyQuestionNum
    - 1];

    if (stModifyQuestion.iStatus != ACTIVE)
    {
    gotoxy(iLEFT_MARGIN, iERROR_LINE);
    cout << cERR_ALREADY_DELETED;
    }
    else
    {
    vDisplayRecord(stModifyQuestion);
    gotoxy(iLEFT_MARGIN, iDELETEMODIFY_QUESTION_LINE);
    cout << "Modify Question (y/n)? ";
    // input and validate answer
    cResponse = cInputLetter (iDELETEMODIFY_QUESTION_LINE,
    cVALID_RESPONSE_LIST,
    cERR_INVALID_YN_RESPONSE, cMANDATORY);

    if (cResponse == 'Y')
    {
    // input and validate question
    vInputString(iQUESTION_LINE,
    stModifyQuestion.cQuestion,
    iQUESTION_LEN, cMANDATORY);

    // input and validate answer
    stModifyQuestion.cAnswer = cInputLetter (iANSWER_LINE,
    cANSWERS,
    cERR_ANSWER, cMANDATORY);

    // input and validate difficult level
    stModifyQuestion.iDifficultyLevel =
    iValidateIntRange(EASY, DIFFICULT,
    cERR_INVALID_DIFFICULTY, iDIFFICULTY_LEVEL_LINE,
    cOPTIONAL);

    // assign status
    stModifyQuestion.iStatus = ACTIVE;

    stQuestionArray[iModifyQuestionNum - 1] =
    stModifyQuestion;

    gotoxy (iCOL_POS, iEND_LINE - 2);
    cout << cQUESTION_MODIFIED_MESSAGE;
    }
    else
    {
    gotoxy (iCOL_POS, iEND_LINE - 2);
    cout << cQUESTION_NOT_MODIFIED_MESSAGE;
    }
    }
    }

    /******************************************************************************
    Name: vDeleteQuestion
    Purpose: To delete a question as requested by user.
    This is done
    by setting the status of the question to DELETE
    Pass: Reference to questions array (array of structs)
    Number of questions (int)
    Return: None
    *******************************************************************************/
    void vDeleteQuestion(stQuestion stQuestionArray[])
    {
    int iDeleteQuestionNum,
    iLastActiveQuestionNum;
    char cResponse;

    // display heading and template
    vDisplayTemplate(cDELETE_QUESTION_HEADING);

    iLastActiveQuestionNum =
    iDetermineLastActiveQuestionNum
    (stQuestionArray, iMAX_QUESTIONS);

    iDeleteQuestionNum = iValidateIntRange(1,
    iLastActiveQuestionNum,
    cERR_INVALID_QUESTION_NUMBER, iQUESTION_NUMBER_LINE,
    cMANDATORY);

    if (stQuestionArray[iDeleteQuestionNum - 1].iStatus !=
    ACTIVE)
    {
    gotoxy(iLEFT_MARGIN, iERROR_LINE);
    cout << cERR_ALREADY_DELETED;
    }
    else
    {
    vDisplayRecord(stQuestionArray[iDeleteQuestionNum -
    1]);
    gotoxy(iLEFT_MARGIN, iDELETEMODIFY_QUESTION_LINE);
    cout << "Delete Question (y/n)? ";
    // input and validate answer
    cResponse = cInputLetter (iDELETEMODIFY_QUESTION_LINE,
    cVALID_RESPONSE_LIST,
    cERR_INVALID_YN_RESPONSE, cMANDATORY);

    if (cResponse == 'Y')
    {
    // change status to deleted
    stQuestionArray[iDeleteQuestionNum - 1].iStatus =
    DELETED;

    gotoxy (iCOL_POS, iEND_LINE - 2);
    cout << cQUESTION_DELETED_MESSAGE;
    }
    else
    {
    gotoxy (iCOL_POS, iEND_LINE - 2);
    cout << cQUESTION_NOT_DELETED_MESSAGE;
    }
    }
    }

    /******************************************************************************
    Name: vGenerateQuestions
    Purpose: To randomly generate a set of questions as
    required by the user
    Pass: Reference to questions array (array of structs)
    Number of questions (int)
    Return: None
    *******************************************************************************/

    void vGenerateQuestions(stQuestion stQuestionArray[],
    int iNumQuestions)
    {
    const char cHOW_MANY_QUESTIONS[] = "How many
    questions? ";

    // this line number is only used for generating
    questions
    const int iNUM_QUESTIONS_LINE = iQUESTION_NUMBER_LINE;


    int iNumberOfQuestions,
    iLastActiveQuestionNum,
    *piGeneratedQuestionIndexes;

    clrscr();

    gotoxy (iLEFT_MARGIN, iHEADING_LINE);
    cout << ' ' << cMAIN_HEADING << endl << endl;
    cout << ' ' << cGENERATE_QUESTIONS_HEADING << endl <<
    endl;

    // determine last active questions
    iLastActiveQuestionNum =
    iDetermineLastActiveQuestionNum
    (stQuestionArray, iMAX_QUESTIONS);

    //if there is at least one active question
    if (iNumQuestions == 0)
    {
    gotoxy(iLEFT_MARGIN, iERROR_LINE);
    cout << cERR_NO_QUESTIONS;
    }
    else
    {
    gotoxy (iLEFT_MARGIN, iNUM_QUESTIONS_LINE);
    cout << ' ' << setw(20) << cHOW_MANY_QUESTIONS;

    // input the number of questions to be generated that
    must be
    // validated to be between 1 and the number of active
    questions.
    iNumberOfQuestions = iValidateIntRange(1,
    iNumQuestions,
    cERR_INVALID_NUM_OF_QUESTIONS, iNUM_QUESTIONS_LINE,
    cMANDATORY);

    // dynamically allocate space to store the generated
    questions indexes
    piGeneratedQuestionIndexes = new
    int[iNumberOfQuestions];

    // generate questions and store the index numbers for
    those questions
    // in this dynamically allocated array
    piGeneratedQuestionIndexes =
    vRandomlyGenerateNumbers(iNumberOfQuestions,
    iLastActiveQuestionNum, stQuestionArray);

    // output the questions
    vDisplayGeneratedQuestions(piGeneratedQuestionIndexes,
    iNumberOfQuestions, stQuestionArray);

    gotoxy (iCOL_POS, iEND_LINE - 2);
    cout << cQUESTIONS_GENERATED_MESSAGE;
    }
    }




  • /******************************************************************************
    Name: vRandomlyGenerateNumbers
    Purpose: Randomly generates numbers that represent
    indexes in the question
    array, ensuring that the index chosen does not contain
    an inactive question
    or a repeat of a previous randomly generated index
    Pass: Number of questions to generate (int)
    Maximum number of active questions in array (int).
    Since the array
    can store both active and inactive questions, the
    maximum number of
    questions may be different from the actual number of
    questions in the
    system
    Reference to questions array (array of structs)
    Return: Pointer to array of generated indexes
    *******************************************************************************/

    int *vRandomlyGenerateNumbers(int iNumbersToGenerate,
    int iMaximumQuestions,
    stQuestion stQuestionArray[])
    {
    bool bRepeatError = true;
    int iRandomNumber, *iGeneratedNumber;
    time_t t; // used for seeding the random number
    generator

    // dynamically allocate space to store the generated
    indexes
    iGeneratedNumber = new int [iNumbersToGenerate];

    // seed/initialise random number generator
    srand((unsigned) time(&t));

    for (int i = 0; i iOUTPUTS_PER_PAGE)
    {
    iOutputCount++;

    // if the number of questions per page exceeds the
    // allowed outputs, need to output them to a new page
    if (iOutputCount >= iOUTPUTS_PER_PAGE)
    {
    iOutputCount = 0;
    vPause();
    vHeadings();
    }
    }
    }
    }

    /*******************************************************************************
    Name: vHeadings
    Purpose: To display the questions output heading
    Pass: Nil
    Return: Nil
    *******************************************************************************/

    void vHeadings()
    {
    clrscr();
    gotoxy (iLEFT_MARGIN, iHEADING_LINE);
    cout << ' ' << cMAIN_HEADING << endl << endl;
    cout << ' ' << cGENERATED_QUESTIONS_HEADING << endl
    << endl;
    }

    /****************************************************************************
    Name: vWriteFile
    Purpose: To write all question records to a file for
    permanent storage
    overwriting any previous data the file may have.
    Pass: Reference to Question array (array of structs)
    Number of last active question in array (int)
    Return: Count of the number of records written to file
    *****************************************************************************/

    int vWriteFile (stQuestion stQuestionArray[], int
    iLastActiveQuestion)
    {
    ofstream questionFile;
    int iCount = 0;

    questionFile.open (cTESTBANK_FILE_NAME);
    if (questionFile)
    {
    for (int i = 0; i < iLastActiveQuestion; i++)
    {
    // only write active questions to file
    if (stQuestionArray[i].iStatus == ACTIVE)
    {
    questionFile << stQuestionArray[i].cQuestion << endl
    << stQuestionArray[i].cAnswer << endl
    << stQuestionArray[i].iDifficultyLevel << endl;
    iCount++;
    }
    }
    }
    else
    {
    gotoxy (iLEFT_MARGIN, iERROR_LINE);
    cout << cERR_FILE_OPEN_MSG << cTESTBANK_FILE_NAME;
    }
    questionFile.close();

    return iCount;
    }

    /*******************************************************************************
    Name: vDisplayRecord
    Purpose: To display a specific question's details on
    the screen
    Pass: The question record to be displayed
    Return: Nil
    *******************************************************************************/
    void vDisplayRecord(stQuestion stQuestionRecord)
    {
    gotoxy (iCOL_POS, iQUESTION_LINE);
    clreol();
    cout << stQuestionRecord.cQuestion;
    gotoxy (iCOL_POS, iANSWER_LINE);
    clreol();
    cout << stQuestionRecord.cAnswer;
    gotoxy (iCOL_POS, iDIFFICULTY_LEVEL_LINE);
    clreol();
    cout << stQuestionRecord.iDifficultyLevel;
    }

    /*******************************************************************************
    Name: vPause
    Purpose: To pause the program using a standard
    message,
    to enable the user to read the screen.
    Pass: Nil
    Return: Nil
    *******************************************************************************/
    void vPause()
    {
    gotoxy (iCOL_POS, iEND_LINE);
    cout << cANY_KEY_MSG;
    getch();

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

In this Discussion