-2
/*Matt Boler
meb0054
hw5.cpp
Compile with gcc in cygwin
*/

#import <iostream>
#import <string>
#import <sstream>
#import <cstdlib>
#import <climits>
#import <assert.h>
using namespace std;

//#define UNIT_TESTING

struct TriviaNode
{
string question;
string answer;
int points;
TriviaNode *next;
};

typedef TriviaNode* NodePtr;

//Input: (1) root is the linked list to be added to
//       (2) Question is the question for the node to ask
//       (3) Answer is the answer to the node's question
//       (4) Points is the point value of the node
//This adds a node to the end of the list
void appendNode(NodePtr& root, string question, string answer, int points);

//Input: (1) root is the linked list to get the length of
//Output: Returns the number of nodes in the linked list
//This calculates the number of nodes in a list
int getListLength(NodePtr& root);

//Input: (1) root is the node to start the list from
//This generates a hardcoded trivia list with 3 predefined questions and answers
void generateHardCodedList(NodePtr& root);

//Input: (1) root is the linked list containing questions to be asked
//       (2) numQuestions is the number of questions to be asked from the list 
//Output: returns o if answered correctly and 1 if answered incorrectly
//This asks the user a question
int askQuestion(NodePtr& root, int numQuestions);


int main()
{
#ifdef UNIT_TESTING
NodePtr head;
cout << "*** This is a debugging version ***" << endl;
cout << "Unit Test Case 1: Ask no questions. The program should give a warning" <<endl;
askQuestion(head, 0);
cout << "Test Case passed..." << endl;

generateHardCodedList(head);
cout << "Unit Test Case 2.1: Ask one question. The tester enters an incorrect answer" << endl;
assert(askQuestion(head, 1) == 1);
cout << "Test Case passed..." << endl;

cout << "Unit Test Case 2.2: Ask one question. The tester enters a correct answer" << endl;
assert(askQuestion(head, 1) == 0);
cout << "Test Case passed..." << endl;

cout << "Unit Test Case 3.1: Ask all questions. The tester enters incorreect answers" << endl;
assert(askQuestion(head, 1) == 1);
assert(askQuestion(head, 2) == 1);
assert(askQuestion(head, 3) == 1);
cout << "Test Case passed..." << endl;

cout << "Unit Test Case 3.2: Ask all questions. The tester enters correect answers" << endl;
assert(askQuestion(head, 1) == 0);
assert(askQuestion(head, 2) == 0);
assert(askQuestion(head, 3) == 0);
cout << "Test Case passed..." << endl;

cout << "Unit Test Case 4: Ask 5 questions in the linked list" << endl;
askQuestion(head, 5);
cout << "*** END OF THE DEBUGGING VERSION ***" << endl;

#else
{
cout << "Welcome to Matt Boler's Trivia Quiz Game!" << endl;
string userContinue = "";
string no = "No";
NodePtr head;
int numQuestions = 3;
generateHardCodedList(head);
while(userContinue.compare(no) != 0)
{
string question, answer;
int score;
cout << "Enter a question:";
getline(cin, question);

cout << "Enter an answer:";
getline(cin, answer);

cout << "Enter award points:";
cin >> score;

cin.clear();
cin.ignore(INT_MAX, '\n');

cout << "Continue? (Yes/No)" << endl;
getline(cin, userContinue);
numQuestions++;
}
//ANYTHING PAST HERE IN THE ELSE BLOCK FAILS VIA SEGFAULT OR JUST NOT RUNNING. NO IDEA WHY
int score = 0;
NodePtr cur = head;
for(int x = 1; x < numQuestions; x++)
{
cur = cur->next;
if(askQuestion(head, x) == 0)
{
  score += cur-> points;
}

}
cout << "Your score is: " << score << endl;
}






#endif
return 0;
}

void appendNode(NodePtr& root, string q, string ans, int pts)
{
NodePtr cur;
NodePtr pre;

cur = new TriviaNode;
assert(cur != NULL);

cur->question = q;
cur->answer = ans;
cur->points = pts;
cur->next = NULL;

if (root == NULL)
root = cur;
else
{
pre = root;
while (pre->next != NULL)
{
  pre = pre->next;
}

pre->next = cur;
}  
}

void generateHardCodedList(NodePtr& root)
{
string q1 = "How long was the shortest war on record? (Hint: how many     minutes)";
string ans1 = "38";
int pts1 = 100;

string q2 = "What was the Bank of America's original name? (Hint: Bank of Italy or Bank of Germany)";
string ans2 = "Bank of Italy";
int pts2 = 50;

string q3 = "What is the best-selling video game of all time? (Hint: Call of Duty or Wii Sports)";
string ans3 = "Wii Sports";
int pts3 = 20;

appendNode(root, q1, ans1, pts1);
appendNode(root, q2, ans2, pts2);
appendNode(root, q3, ans3, pts3);
}

int askQuestion(NodePtr& root, int numQuestions)
{
NodePtr cur;
cur = root;
if(numQuestions > getListLength(root))
{
cout << "Warning: there aren't that many questions in the list" << endl;
}
else if(numQuestions < 1)
{
cout << "Warning: the number of trivia to be asked must be greater than or equal to one" << endl;
}
else
{
for(int i = 1; i < numQuestions; i++)
{
  cur = cur->next;
}
cout << "Question: " << cur->question << endl;
cout << "Player answer: ";
string player_answer;

getline(cin, player_answer);
cin.clear();

if (player_answer == cur->answer)
{
  cout << "Your answer is correct. You recieve " << cur->points << " points." << endl;
  return 0;
}
else
{
  cout << "Your answer is wrong. The correct answer is: " << cur->answer << endl;
}
}
return 1; 
}

int getListLength(NodePtr& root)
{
if(root == NULL)
{
return 0;
}
int count = 0;
NodePtr cur = root;
while(cur != NULL)
{
cur = cur->next;
++count;
}
return count;
}

This is a program to add trivia questions to a linked list in c++. Anything after the while loop causes an error. Specifically, initializing an int causes a segfault; trying to print to console with cout refuses to print anything out.

1 Answers1

2

In the current version of the code your generateHardCodedList pases the root pointer to appendNode functions without initializing it. The calling code did not initialize root (called head in main), generateHardCodedList does not initialize it either, so appendNode receives a garbage pointer as root. After that all bets are off: your program is already broken.

I don't know why in your case it crashes so much later in the code, but it doesn't matter anyway. Your generateHardCodedList call is already broken.

Either initialize your head pointer with nullptr before passing it to generateHardCodedList, or better initialize it to nullptr inside generateHardCodedList, before trying to call appendNode.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765