I have just started to learn C++ and have been working on a few problems to hone my skills. Currently I am having a problem swapping some values of my array of records. The input validation works fine but then when I try to swap the values around the program stops responding and crashes. Here is how I have created it:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int grandprixnum;
struct DriverData {
string driver;
int car;
string team;
int grid;
int points;
};
DriverData * grand = new DriverData[grandprixnum];
int input()
{
cout << "How many drivers where there? ";
cin >> grandprixnum;
cin.sync();
DriverData * grand = new DriverData[grandprixnum];
for (int i=0; i<grandprixnum; i++)
{
cout << "Driver numbers: "<< i+1 << " \n";
cout << "What is the drivers name? \n";
getline (cin, grand[i].driver);
cin.sync();
cout << "What is the drivers car number? \n";
cin >> grand[i].car;
while (grand[i].car > 99 || grand[i].car < 1)
{
cout << "Please enter a value between 1 and 99! \n";
cin >> grand[i].car;
}
cin.sync();
cout << "What team is the driver racing for? \n";
getline (cin, grand[i].team);
cin.sync();
cout << "What grid are they in? \n";
cin >> grand[i].grid;
cin.sync();
while (grand[i].grid < 0 || grand[i].grid > 22)
{
cout << "Please enter a grid number between 1 and 22! \n";
cin >> grand[i].grid;
}
cin.sync();
cout << "What are their total points? \n";
cin >> grand[i].points;
cin.sync();
while (grand[i].points > 25 || grand[i].points < 0)
{
cout << "Please enter the drivers points between 0 and 25! \n";
cin >> grand[i].points;
}
}
}
int sorting ()
//This part _______________________________
{
for(int a=1; a<=grandprixnum; a++)
{
for(int b=0; b<=grandprixnum; b++)
{
if(grand[b].points < grand[b+1].points)
{
swap(grand[b].driver, grand[b+1].driver);
swap(grand[b].car, grand[b+1].car);
swap(grand[b].team, grand[b+1].team);
swap(grand[b].grid, grand[b+1].grid);
swap(grand[b].points, grand[b+1].points);
}
}
}
}
//To here_________________________________
int showtable ()
{
cout << "Driver Car Team Grid Points \n";
for(int c=0; c<grandprixnum; c++)
{
cout << grand[c].driver << grand[c].car << grand[c].team << grand[c].grid << grand[c].points << "\n";
}
}
int main()
{
input ();
sorting ();
showtable ();
}
I have looked around and cannot find an example or someone having the same problem as me. If someone could show me what is wrong with it. Thank you in advance.
EDIT: I have tested the swap before and it does work but it seems to struggle with the array of records.
You access to your array out of bounds. Your array has a length of grandprixnum so you can access to elments from 0 to grandprixnum-1
for(int a=1; a < grandprixnum; a++)
// ^
{
for(int b=0; b < grandprixnum-1; b++)
// ^ ^^ -1 because of b+1
{
if(grand[b].points < grand[b+1].points)
{
...
}
}
}
If ter is nothing to return in a function you dont need a return type. Use void sorting(), void input(), void showtable()
You declareted your array grand twice. On time global and second time local in function input. Declare it global and allocate it in function input.
DriverData * grand = NULL;
int input()
{
...
grand = new DriverData[grandprixnum];
Remove equal sign from this line:
for(int b=0; b<=grandprixnum; b++)
So it will be like this:
for(int b=0; b<grandprixnum; b++)
And replace this line
DriverData * grand = new DriverData[grandprixnum];
with
grand = new DriverData[grandprixnum]; // will store in global variable
Related
I'm trying to dynamically allocate an array from a structure. I've look on a couple of other pages on stackoverflow and tried some some code, but none seems to work for my case. The closest I've found to what I'm doing is here:
C++ dynamic memory allocation with arrays in a structure
For some reason when I use this line of code:
cin >> testsPtr[i].students;
I get the error in the title. I've also tried using:
cin >> testsPtr[i]->students;
How can I have the user enter the data for my program?
Here are the specifications for the programming challenge:
Modify the program of Programming Challenge 1 to allow the user to enter name-score pairs. For each student taking a test, the user types a string representing the name of the student, followed by an integer representing the students score. Modify both the sorting and average-calculating functions so they take arrays of structures, with each structure containing the name and score of a single student. In traversing the arrays, use pointers rather than array indices.
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
void averageScore(double*, int);
void sort(double*, int);
int numScores;
struct studentScores {
double *scores;
string *students;
};
cout << "How many test scores will you be entering?" << endl;
cin >> numScores;
studentScores *testsPtr = new studentScores[numScores];
for (int i = 0; i < numScores; i++) {
cout << "What is the #" << i + 1 << " students name?" << endl;
cin >> testsPtr[i].students;
for (int j = 0; j < numScores; j++) {
cout << "Please enter test score #" << j + 1 << endl;
do {
cin >> testsPtr[j].scores;
if (testsPtr[i].scores < 0) {
cout << "A test score can't be less than 0. Re-enter test score #" << i + 1 << endl;
}
} while (testsPtr[i].scores < 0);
}
}
cout << endl;
/*sort(testsPtr.scores, numScores);
cout << endl;
averageScore(testScores, numScores);
cout << endl;*/
for (int i = 0; i <= numScores; i++) {
cout << testsPtr->students << " test scores are: " << endl;
for (int j = 0; j <= numScores; j++) {
cout << testsPtr->scores;
}
}
delete[] testsPtr;
testsPtr = nullptr;
return 0;
}
Dereference pointer before reading value:
cin >> *(testsPtr[i].students);
But before you have to create object string and reference pointer to it:
testsPtr[i].students = new string;
The fix to your problem is to change your cin line to this cin >> *(testsPtr[i].students); this is because testsPtr[i].students is a pointer so you have to use the deference pointer. Make sure you correctly initialize the members.
Hope this helps.
How to fix the code? I can't use vectors. I need to be able to call the names for the courses from the first while to the second one and display them.
cout << "Please enter the number of classes"<< endl;//Number of classes for the while
cin >> nclass;
while (count <= nclass ) // while
{
//Information for the class
{
cout << "Please enter the course name for the class # "<< count << endl;
getline (cin, name);
string name;
string coursename[nclass];
for (int i = 0; i < nclass; i++) {
coursename[i] = name;
}
}
char choose;
cin >> choose;
while ( choose == 'B' || choose == 'b') {//Name the courses
for (int x = 0; x < nclass; x++){
cout << "Here is a list of all the courses: \n" << coursename[i] << endl;
}
return 0 ;
}
you are declaring coursename as local inside loop and then using it outside so you get a compile time error (coursename is undeclared identifier).
one question: what is the role of inner for-loop????!!!
you use a for loop inside while loop through which you are assigning all the elements the same value as the string name has!!!
so every time count increments the inner for loop assigns the new value of name after being assigned, to the all elements of coursename.
count is undefined! so declare it and initialize it to 1 or 0 and take this in mind.
you wrote to the outbounds of coursname: count <= nclss to correct it:
while(count < nclass)...
another important thing: clear the input buffer to make cin ready for the next input. with cin.ignore or sin.sync
cout << "Please enter the number of classes"<< endl;//Number of classes for the while
cin >> nclass;
string coursename[nclass];
int count = 0;
while (count < nclass ) // while
{
//Information for the class
string name;
cout << "Please enter the course name for the class # "<< count << endl;
cin.ignore(1, '\n');
getline (cin, name);
coursename[count] = name;
cin.ignore(1, '\n');
count++;
}
char choose;
cin >> choose;
while ( choose == 'B' || choose == 'b') {//Name the courses
for (int x = 0; x < nclass; x++){
cout << "Here is a list of all the courses: \n" << coursename[x] << endl;
}
This code works!
#include <iostream>
#include <string>
using namespace std;
int main()
{
int nclass = 0, count = 1, countn = 1;
string name[100];
cout << "Please enter the number of classes" << endl;
cin >> nclass;
while (count <= nclass) {
cout << "Please enter the course name for the class # " << count << endl;
cin >> name[count];
count++;
}
cout << "Here is a list of all the courses: " << endl;
while (countn <= nclass) {
cout << name[countn] << endl;
countn++;
}
return 0;
}
Note that gave the array "name" the size of 100. Nobody is going to have 100 classes! There is no need for the for loops. It is a good practice to initialize the count and the new count which is designated by countn. Why is my answer voted down when it works?
I've come across a little problem, how do I print the winning candidate's name? See the instructions here are, input five names, their number of votes and percentage of votes, whoever has the highest wins. I don't know if I did my code right, but it works.. well except for the name part. I've tried everything from a lot of for loops to transfer the array or what.
I'm almost done with the code.
Here's the code
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
char candidates[50];
int votes[5]={0};
float percent[5]={0};
int a,b,c,d,e,i;
int maxx;
int champ=0;
char winner[50];
cout << "Enter the candidates' last names: ";
cout << endl;
for(a=1;a<=5;a++)
{
cout << a << ". ";
cin >> candidates;
}
cout << endl;
cout << "Enter their number of votes: " << endl;
for(b=1;b<=5;b++)
{
cout << b << ". ";
cin >> votes[b];
}
cout << endl;
cout << "percentage of votes: " << endl;
for(c=1;c<=5;c++)
{
cout << c << ". ";
percent[c]=votes[c]*0.2;
printf("%.2f\n", percent[c]);
}
cout <<"Candidates\t\tVotes\t\t% of Votes" << endl;
for(int k=1;k<=5;k++)
{
cout << candidates[k] << "\t\t\t" << votes[k] << "\t\t\t";
printf("%.2f\n", percent[k]);
}
maxx=percent[0];
for(d=1;d<=5;d++)
{
if(maxx<percent[d]);
{
//what happens here?
}
}
return 0;
}
You should keep a 2d array of characters or array of string for storing candidate names instead of a 1-d array.
char candidates[5][10]; //
for(int i = 0; i < 5; i++)
{
cin >> candidates[i];
}
Then keep a variable to store index for winning candidate
int winIndex = 0;
int winPercent = 0;
for(int i = 0; i < 5; i++)
{
if(percent[i] > winPercent)
{
winPercent = percent;
winIndex = i;
}
}
Finally print name of winning candidate;
cout << candidates[winIndex];
In object oriented approach, you may create a class with following information
class Candidate
{
string name;
int votes;
float percent;
};
Use string candidates[50]; instead of char candidates[50];
then cin >> candidates[a];
In a problem i am working on i have a function that checks if the number of spherical and cylindrical holes in rectangular block are greater than zero. In this problem i have to call the function twice. My problem is that the first time i call the function 'HoleCheck' is is running twice and assuming that zero is entered in for the cylindrical holes and makes me re-enter the value for spherical holes. How can i make it to only run once for the spherical hole check?
#include <iostream>
#include <string>
using namespace std;
void Check(double arr1[], string arr2[]);
void HoleCheck(int arr3[], string arr4[]);
int main()
{
double DimArray[3];
string MyArray[3] = { "Height", "Length", "Width"};
int totalholes[2];
string holes[2] = { "Spherical", "cylindrical"};
cout << "Enter the height, length and width of rectangle in centimeters: ";
cin >> DimArray[0] >> DimArray[1] >> DimArray[2];
Check(DimArray, MyArray);
cout << "How many spherical bubbles are present? ";
cin >> totalholes[0];
HoleCheck(totalholes, holes);
cout << "How many cylindrical holes are present? ";
cin >> totalholes[1];
HoleCheck(totalholes, holes);
return 0;
}
void Check(double arr1[], string arr2[])
{
int i;
for (i = 0; i < 3; i++)
{
while (arr1[i] <= 0)
{
cout << "Your entered " << arr2[i] << " is less than zero!\n";
cout << "Please re-enter a valid number --> ";
cin >> arr1[i];
}
}
}
void Check(double arr1[], string arr2[])
{
int z;
for (z = 0; z < 2; z++)
{
while (arr3[z] <= 0)
{
cout << "The number of " << arr4[z] << " holes must be greater than 0.\n";
cout << "Please re-enter a valid number --> ";
cin >> arr3[z];
}
}
}
Assuming that your second Check function is actually HoleCheck and that was a typo:
Your HoleCheck Function checks both elements of its arr3, but you are calling it before you enter any values into totalHoles[1].
Either just remove the first call to HoleCheck or change it so you can tell it which entry in the array to check.
So I've graduated from learning C and now learning C++. From what I understand C and C++ are similar in variety of ways so I'm trying to re-write my past C project files into C++. However I keep getting a memory leak when I try to print out my information. Can someone tell me why I am getting a memory leak in my code.
struct.h
typedef struct student_info {
char last[10];
char first[10];
int student_id;
int count_student;
} student;
typedef struct course_info {
char name[10];
int course_id;
int count_course;
student *students;
} course;
typedef struct gradebook_info {
course *courses;
} gradebook;
function.c
void new_course(gradebook *info) {
int i, loop=0;
cout << "Enter Number of Courses " ;
cin >> loop;
for(i=0; i<loop; i++) {
cout << "Enter Course ID ";
cin >> info->courses[info->courses->count_course].course_id;
cout << "Enter Course Name ";
cin >> info->courses[info->courses->count_course].name;
info->courses->count_course++;
}
}
void new_student(gradebook *info) {
int i, loop=0;
cout << "Enter Number of Students " ;
cin >> loop;
for(i=0; i<loop; i++) {
cout << "Enter Student ID ";
cin >> info->courses->students[info->courses->students->count_student].student_id;
cout << "Enter Last Name ";
cin >> info->courses->students[info->courses->students->count_student].last;
cout << "Enter First Name ";
cin >> info->courses->students[info->courses->students->count_student].first;
info->courses->students->count_student++;
}
}
void printCourse(gradebook *info) {
int i;
cout << "Course ID\tCourse Name\t" << endl;
for(i=0; i<info->courses->count_course; i++) {
cout << info->courses[i].course_id << "\t\t";
cout << info->courses[i].name << endl;
}
}
void printStudent(gradebook *info) {
int i;
cout << "Student ID\tLast Name\tFirst Name\t" << endl;
for(i=0; i<info->courses->students->count_student; i++) {
cout << info->courses->students[i].student_id << "\t\t";
cout << info->courses->students[i].last << "\t\t";
cout << info->courses->students[i].first << endl;
}
}
When I run new_course() function it works.
I run my printCourse() function it works.
I run new_student() function it works.
When I run printStudent() function it works.
Then I try to run printCourse() function again and when i=2, I get some information from my struct student.
I can't figure it out. Any help is appreciated.
main.c
gradebook *info = new gradebook; //allocate memory
do {
main_menu();
int option=0;
switch(option) {
case 1: new_course(info);
break;
case 2: new_student(info);
break;
case 3: printCourse(info);
break;
case 4: printStudent(info);
break;
}
}while(option < 13);
delete(info);
You need to allocate the pointers students and course using new.
After getting loop:
students = new student_info* [loop]
and
courses= new course_info* [loop]
You have not only to allocate memory for the gradebook, but also for the courses and the students. For example:
gradebook *info = new gradebook;
info->courses = new course_info[10];
for(int i = 0; i < 10; i++)
info->courses[i]->students = new student_info[10];
Beware, this example limits the number of courses and students per course to 10.
P.S.: Your code might work for one or two iterations if you don't allocate memory for the courses and the students. But in this case you screw up your memory.