Discerning between struct indexing and size initialization - c++

I'm trying to write a function that takes an array of structs and will sort the elements of the array alphabetically by accessing the first data member. I'm struggling to get the code to distinguish between when I'm referring to a data member versus initializing the size of an array. For example, the following code
void selectionSort(struct A[], int size)
{
int mindex;
for (int ct1 = 0; ct1 < size - 1; ct1++)
{
mindex = ct1;
for (int ct2 = ct1 + 1; ct2 < size; ct2++)
if (A[ct2].state < A[mindex].state)
mindex = ct2;
swap(A[mindex], A[ct1]);
}
}
complains that ct2 is not constant, when I'm clearly using it as an index. How would I get this to run correctly? That is, how can I get it to compare data members in their respective indices rather than think I'm initializing the size of a struct variable?
Edit The error message I am receiving is expression must have a constant value for the variable ct2.

I think you might have a problem with how you're creating your function. Usually, when you declare an array of structs it looks like this.
struct Student {
int uid;
string name;
};
Student studentArry[3];
You would use 'Student' or the name of your struct to initialize your array. For example, int arr[10] is an integer array of size 10 while Student arr[10] is a student array of size 10.
One other side note, if you're trying to create a function that is passed a struct you have to initialize the struct before you define the function. This code will work because the struct was declared before the function was.
#include <iostream>
using namespace std;
struct Student {
int uid;
string name;
};
void print(Student array[], int size){
for(int i = 0; i < size; i++){
cout << array[i].uid << endl;
cout <<array[i].name<< endl;
}
};
int main(){
Student StudentRecords[2] = {
{19, "John Smith"},
{21, "Jim Pop"}
};
print(StudentRecords, 2);
return 0;
}
The code below will not because the print function doesn't know what type student is.
#include <iostream>
using namespace std;
void print(Student array[], int size){
for(int i = 0; i < size; i++){
cout << array[i].uid << endl;
cout <<array[i].name<< endl;
}
};
int main(){
struct Student {
int uid;
string name;
};
Student StudentRecords[2] = {
{19, "John Smith"},
{21, "Jim Pop"}
};
print(StudentRecords, 2);
return 0;
}
So, all in all, I think you need to change how you're creating the parameter for the function and possible where you're declaring your struct.

Related

Code exiting when Dynamic Array of class allocated

I am trying to dynamically allocate an array and whenever it gets to the part where it dynamically allocates the program exits. I would rather not use vectors as I am trying to learn how to do this using dynamic arrays.
This is the simplified code:
#include <iostream>
#include <string>
using namespace std;
class Student
{
private:
double calcAverage(double* testArray);
char calcGrade(double average);
public:
int nTests, sameTests, idNum;
string name;
double average, *testArray;
char grade;
};
int i;
Student fillStudentArray(int nStudents);
int main()
{
*studentArray = fillStudentArray(nStudents);
return 0;
}
Student fillStudentArray(int nStudents)
{
Student *newStudentArray = new Student[nStudents];
cout << "If you can see this I worked. ";
delete[] studentArray;
return *newStudentArray;
}
I have tried the solution posted here Creation of Dynamic Array of Dynamic Objects in C++ but it also exits in a similar way. The main for the code looks like this.
int main()
{
int nStudents = 3; //this number is just for testing, in actual code it has user input
Student** studentArray = new Student*[nStudents];
cout << "1 ";
for(i = 0; i < nStudents; i++)
{
cout << "2 ";
studentArray[i] = new Student[25];
cout << "3 ";
}
return 0;
}
close (heres a cigar anyway)
Student* fillStudentArray(int nStudents); <<== function must return pointer to students
int main()
{
int nStudents = 3; <<<=== declared nstudents
Student *studentArray = fillStudentArray(nStudents); <<< declare studentArray
return 0;
}
Student *fillStudentArray(int nStudents) <<<== return pointer
{
Student* newStudentArray = new Student[nStudents];
cout << "If you can see this I worked. ";
// delete[] studentArray; <<<== what were you trying to delete?
return newStudentArray; <<<=== return pointer
}
the second code you showed is not relevant, its creating a 2d array

Calling name for passing two arrays (a string and an int) to a function in C++

I'm aware that when you write the call for your function you write it as displayArray(seasons,10)
with the name of one array and its size. I'm stuck on how you would right the arguments to pass the two arrays listed in my code, seasons and cartoons.
#include<iostream>
#include<string>
#include<iomanip>
using namespace std;
void displayArray(string car[], int sea[], int size);
int main()
{
int seasons[] = {5,10,8,2,12,7,31,9,3,4};
string cartoon[] = { "Steven Universe","Adventure Time","Regular Show","Gravity Falls",
"Spongebob Squarepants","Futurama","The Simpsons","Bob's Burgers","Avatar: The Last Airbender","Rick and Morty"};
displayArray() // Error Message here
}
void displayArray(string car[], int sea[], int size)
{
for (int x = 0; x < size; x++)
{
cout << " " << car[x] << "\t\t" << sea[x] << right << endl;
}
}
So you have to first create an array to pass your values with. Then just pass the array.
void function(int arr[]) {}
int arr[] = { 1, 2, 3, 4, 5 };
function(arr);
So in your code above, it should look like this:
int main()
{
int seasons[] = {5,10,8,2,12,7,31,9,3,4};
string cartoon[] = { "Steven Universe","Adventure Time","Regular Show","Gravity Falls",
"Spongebob Squarepants","Futurama","The Simpsons","Bob's Burgers","Avatar: The Last Airbender","Rick and Morty"};
displayArray(cartoon, seasons, 10);
}
Hope this helps :)
displayArray(cartoon, seasons, 5);
This seems to work fine for me. You just pass each array in according to whichever is declared first in the function argument list. Am I misunderstanding your question?

C++ compiler error when running code (seg fault core dumped)

#include <iostream>
using namespace std;
/*
Animal cheapest(string type, Animal a[], int size) that returns the
cheapest animal in a of type type (that is, the cheapest cat or dog).
Note: Assuming you’ve
filled in an array of Animals called shelter, calling cheapest from your
main function would
look like
Animal inexpensive = cheapest(“Dog”, shelter, 20);
*/
struct Animal{
string name = "";
string gender = "";
int age = 0;
int price = 0;
string catOrDog = "";
};
Animal cheapest(string type, Animal a[], int size){
int smallest = a[0].price;
int indexOfSmallest = 0;
for(int i = 0; i<size; i++){
if(a[i].price < smallest && a[i].catOrDog == type){
indexOfSmallest = i;
}
}
return a[indexOfSmallest];
}
void printAnimal(Animal name){
cout<< name.name <<endl;
}
int main(){
Animal arr[1];
Animal one;
one.name = "Chad";
one.gender = "Female";
one.age = 2;
one.price = 1500;
one.catOrDog = "Dog";
Animal two;
two.name = "Brian";
two.gender = "Female";
two.age = 2;
two.price = 1000;
two.catOrDog = "Dog";
arr[0] = one;
arr[1] = two;
Animal inexpensive = cheapest("Dog", arr, 2);
printAnimal(inexpensive);
return 0;
}
Segmentation Error when running code. From what I've googled, this usually happens when you are reading from a file but I am not reading from a file.
What is wrong with my code? This is the first time I've encountered a problem like this so I am completely blank
You declare an array with one element:
Animal arr[1];
Then you access it out of bounds by storing two elements into it:
arr[0] = one;
arr[1] = two;
Only the first index (0) is valid.
You should consider using a std::array or std::vector rather than a C-style array, so you don't have to pass its size separately.

Nested structure function in c++

I'm having trouble with one of my assignments (or maybe I'm overthinking it?)
I need to create
a function to take integer parameters for number of students and tests.
Allocate the memory needed for the array of students and the array of test scores for each student.
Return a pointer to the array of Student structures. No display output is done in this function.
int main()
{
int studentNum;
int testNum;
cout << "How many students are there?\n";
cin >> studentNum;
cout << "How many tests are there?";
cin >> testNum;
system("pause");
return 0;
}
my function
GradeBook *initArrays(int s, int t)
{
GradeBook *ptr;
// Allocate the array of Student structures.
ptr = new GradeBook[s];
// Allocate an array of ints (to hold test scores)
// for each element of the array of Student structures.
for (int count = 0; count < s; count++)
{
ptr[count].tests = new int[t];
}
// Return a pointer to the array of structures.
return ptr;
}
edit: I have edited my function, could i get some opinions on that?
if you are writing this in c++, use classes. if i understand correctly, you should create a structure to save a students id,name,or something and a corresponding grade?
something like:
class Test{
public:
int id;
int grade;
Test(int id, int grade){
this->id = id;
this->grade = grade;
}
};
class Student{
public:
int id;
std::string name;
std::vector<Test> tests;
Student(int id, std::string name)
{
this->id = id;
this->name = name;
}
};
int main(){
vector<Student> students;
int studentnum;
for (int i = 0; i < studentnum; i++){
students.push_back(Student(i, "name"));
//insert all tests of the student by calling students[i].tests.push_back(Test(id, grade))
}
}
this way you don't have to allocate memory, which you can easily overlook freeing.
edit:
this is very basic and not a sophisticated solution, as the properties of the classes are all public.
edit 2:
typedef struct Test{
int id;
int grade;
}Test;
typedef struct Student{
int id;
std::string name;
Test * tests;
}Student;
int main(){
Student * students;
int studentnum;
students = (Student*)malloc(sizeof(Student)*studentnum);
for (int i = 0; i < studentnum; i++){
students[i]->id = id;
students[i]->name = "name";
student[i]->tests = (Test*)malloc(sizeof(Test)*numberofgradesofthatstudent);
for (int j = 0; j < numberofgradesofthatstudent; j++)
{
students[i]->tests[j]->id = testid;
students[i]->tests[j]->grade = grade;
}
}
}
this is schematic! new and malloc reserve memory on the heap, do not forget to free everything when you are done with it.
As said a little above, be careful using brackets {} to delimit your blocks.
Secondly,the syntax:
array[studIndex].Tests
supposes that the value array[studIndex] (here an integer) has a member value named Tests. But in this case it doesn't.
Think about your problem: you need to store two values "connected" to one another in a static array. The way I see it, you should try on with two dimensional arrays:
int 2dArray[nbStudents][nbTests];
If you don't want to bother with 2dimensional arrays, you can also try
int 2dArray[nbStudents * nbTests];
But for conveniance, it is often better to use 2d arrays.
Also, think about declaring your array before the for loops in your function.
Then concatenate two for loops as you did and I'll let you think about the rest...

Run-Time Check Failure #2 - Stack around the variable 'IDNumber' was corrupted

#include <iostream>
#include <string.h>
#include <time.h>
using namespace std;
struct MyID
{
char FirstName[10]; // array for lenight of the word.
char LastName[10]; // array for lenight of the word.
int IdNumber;
};
void InitializeArray(MyID IDNumber[], int Size);
//void SortTheArray(MyID IDNumber[], int Size);
int main(){
const int Size = 100;
MyID IDNumber[Size];
strcpy_s(IDNumber[Size].FirstName, "Aziz");
strcpy_s(IDNumber[Size].LastName, "LEGEND");
// I believe the error is around here.
InitializeArray(IDNumber, Size);
//SortTheArray(IDNumber, Size);
}
void InitializeArray(MyID IDNumber[], int Size){
//srand(time(0));
for (int i = 0; i < Size; i++){
//IDNumber[i].IdNumber = rand() %100 ;
cout<<IDNumber[i].FirstName<<endl;
IDNumber[i].LastName;
}
}
I have this problem, every time I want to test my function and struct, this error will prompt. Also, I want to see if my name will print correctly before continue to write rest program. The idea is I want to print same name every time without ask user to print name every time.
Also, I have upload the picture of result if you want to see it.
Because you are using arrays, you are experiencing buffer overrun error:
const int Size = 100;
MyID IDNumber[Size];
strcpy_s(IDNumber[Size].FirstName, "Aziz");
strcpy_s(IDNumber[Size].LastName, "LEGEND");
The expression IDNumber[Size] is equivalent to IDNumber[100].
In C++, array slot indices go from 0 to Size - 1. You are accessing one past the end of the array.
Edit 1: Initializing an array
Based on your comment, you can use a loop to initialize the slots in an array (vector):
struct Person
{
std::string first_name;
std::string last_name;
};
const unsigned int CAPACITY = 100;
int main()
{
std::vector<Person> database(CAPACITY);
Person p;
std::ostringstream name_stream;
for (unsigned int i = 0; i < CAPACITY; ++i)
{
name_stream << "Aziz" << i;
database[i].first_name = name_stream.str();
database[i].last_name = "LEGEND";
}
return 0;
}