Sort names alphabetically - c++

I'm trying to sort names alphabetically
e.g If user enters names and GPA:
Names GPA
Peter 2.8
Robert 5.6
David 7.8
The output should be : -
Names GPA
David 7.8
Peter 2.8
Robert 5.6
Here is my program so far (INCOMPLETE):-
#include <iostream>
using namespace std;
int main()
{
char name [5][25];
float gpa [5];
int i;
for (i=0 ; i<5 ; i++)
{
cout << "Enter name " << i+1 << " : ";
cin >> name [i];
cout << "Enter GPA : ";
cin >> gpa [i];
cout << endl;
}
cout << "\n********** Your entered data **********\n\n";
cout << "\tName" << "\t\t" << "GPA\n\n";
for (i=0 ; i<5 ; i++)
{
cout << "\t" << name [i] << "\t\t" << gpa [i];
cout << endl;
}
for (i=0 ; i<5 ; i++)
{
for (int j=0 ; j<1 ; j++)
{
cout << (int) name [i][j] << endl;
}
}
cout << "\n\n******* Sorted data (w.r.t name) *******\n\n";
cout << "\tName" << "\t\t" << "GPA\n\n";
for (i=0 ; i<5 ; i++)
{
cout << "\t" << name [i] << "\t\t" << gpa [i];
cout << endl;
}
cout << endl;
return 0;
}
Remember, only name should be sorted alphabetically. I have taken the ASCII values of the first characters of entered names in the middle for loop but:-
1- ASCII code for 's' is not the same as 'S' (That's a problem for me)
2- I can't seem create a logic to compare the ASCII values of the first letters of names then sort them accordingly. Then afterwards linking the name with the sorted letter list and displaying the result. Also the GPA should be linked with the names.
Any help would be appreciated.

Here's an answer using std::sort. I changed some of your C-like approach and using std::sort actually forces me to do it. The comparison function(compareStudents) needs objects so I had to create the struct. Vector has been used for the same reason although it would have been possible to keep using arrays but that's generally frowned upon.
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
struct Student {
string name;
float gpa;
Student(string name, float gpa) {
this->name = name;
this->gpa = gpa;
}
};
bool compareStudents(Student a, Student b) {
return a.name.compare(b.name) < 0;
}
int main() {
const int studentCount = 2;
vector<Student> studentVector;
int i;
for (i = 0 ; i < studentCount ; i++) {
cout << "Enter name " << i + 1 << " : ";
string name;
cin >> name;
cout << "Enter GPA : ";
float gpa;
cin >> gpa;
cout << endl;
studentVector.push_back(Student(name, gpa));
}
cout << "\n********** Your entered data **********\n\n";
cout << "\tName" << "\t\t" << "GPA\n\n";
vector<Student>::iterator it = studentVector.begin();
for (; it != studentVector.end(); ++it) {
Student student = *it;
cout << "\t" << student.name << "\t\t" << student.gpa;
cout << endl;
}
sort(studentVector.begin(), studentVector.end(), compareStudents);
cout << "\n\n******* Sorted data (w.r.t name) *******\n\n";
cout << "\tName" << "\t\t" << "GPA\n\n";
it = studentVector.begin();
for (; it != studentVector.end(); ++it) {
Student student = *it;
cout << "\t" << student.name << "\t\t" << student.gpa;
cout << endl;
}
cout << endl;
return 0;
}

If you convert the names' character to upper-case using std::toupper you should then just be able to compare the the strings using < operator.
Edit: if you don't want to use std::sort :-)

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
class stu
{
char name[40];
int cgpa;
public:
void assign()
{cin>>name;
cin>>cgpa;
}
void display()
{cout<<name<<endl<<cgpa<<endl;
}
friend void align(stu *s,int v);
};
void align(stu *s,int v)
{for(int j=0;j<v-1;j++)
{for(int i=0;i<v-j-1;i++)
{//buble sort
if(strcmp((s+i)->name,(s+i+1)->name)>0)
{char l[40];
strcpy(l,(s+i)->name);
strcpy((s+i)->name,(s+i+1)->name);
strcpy((s+i+1)->name,l);
//swapping cgpa
int t=(s+i)->cgpa;
(s+i)->cgpa=(s+i+1)->cgpa;
(s+i+1)->cgpa=t;
}
}}}
int main()
{stu s[10];int i;
for(i=0;i<5;i++)
s[i].assign();
align(s,5);
cout<<endl<<endl;
for(i=0;i<5;i++)
s[i].display();
}

#include <string>
#include <algorithm>
using namespace std;
int main()
{
//zbuduj program wyswietlajacy w kolejnosci alfabetycznej 5 wczytanych imion
string wyrazy[5];
int c;
for(int i=0; i<5;i++){
c= i +1;
cout<<"podaj imie "<<c<<"; ";
cin>>wyrazy[i];
}
sort(wyrazy, wyrazy+5);
cout<<"posortowane"<<endl;
for(int b=0; b<5;b++){
cout<<wyrazy[b]<<endl;
}
return 0;
}

Related

Output does not include all input for my array

I have this program that is barely started:
#include <iostream>
#include <iomanip>
#include <ctime>
#include <string>
using namespace std;
class Grade
{
public:
string studentID;
int userChoice = 0;
int size = 0;
double* grades = new double[size]{0};
};
void ProgramGreeting(Grade &student);
void ProgramMenu(Grade& student);
string GetID(Grade& student);
int GetChoice(Grade& student);
void GetScores(Grade& student);
int main()
{
Grade student;
ProgramGreeting(student);
ProgramMenu(student);
}
// Specification C1 - Program Greeting function
void ProgramGreeting(Grade &student)
{
cout << "--------------------------------------------" << endl;
cout << "Welcome to the GPA Analyzer! " << endl;
cout << "By: Kate Rainey " << endl;
cout << "Assignment Due Date: September 25th, 2022 " << endl;
cout << "--------------------------------------------" << endl;
GetID(student);
cout << "For Student ID # " << student.studentID << endl;
}
void ProgramMenu(Grade &student)
{
cout << "--------------------------------------------" << endl;
cout << setw(25) << "Main Menu" << endl;
cout << "1. Add Grade " << endl;
cout << "2. Display All Grades " << endl;
cout << "3. Process All Grades " << endl;
cout << "4. Quit Program." << endl;
cout << "--------------------------------------------" << endl;
GetChoice(student);
}
string GetID(Grade &student)
{
cout << "Enter the student's ID: ";
cin >> student.studentID;
if (student.studentID.length() != 8) {
cout << "Student ID's contain 8 characters ";
GetID(student);
}
return student.studentID;
}
int GetChoice(Grade &student)
{
cout << "Enter your selection: ";
cin >> student.userChoice;
if (student.userChoice == 1) {
GetScores(student);
}
else if (student.userChoice == 2)
{
}
else if (student.userChoice == 2)
{
}
else if (student.userChoice == 4)
{
exit(0);
}
else
{
cout << "Please enter 1, 2, 3 or 4" << endl;
GetChoice(student);
}
}
void GetScores(Grade &student)
{
int count = 0;
double score = 0;
cout << "How many test scores would you like to enter for ID# "
<< student.studentID << "? ";
cin >> student.size;
while (count != student.size) {
cout << "Enter a grade: ";
cin >> score;
for (int i = 0; i < student.size; i++) {
student.grades[i] = score;
}
count++;
}
for (int i = 0; i < student.size; i++) {
cout << student.grades[i] << " ";
}
}
I am trying to make sure my array is recording all test scores, but when I output the array in my GetScore function, each element in the array is the same or equal to the last score I entered. For example, if I choose 3 for size and then enter three values of 99.2 86.4 90.1, all three elements will read 90.1.
Why is this happening?
Your Grade class is allocating an array of 0 double elements (which is undefined behavior), and then your GetScores() function does not reallocate that array after asking the user how many scores they will enter, so you are writing the input values to invalid memory (which is also undefined behavior).
Even if you were managing the array's memory correctly (ie, by using std::vector instead of new[]), GetScores() is also running a for loop that writes the user's latest input value into every element of the array, instead of just writing it to the next available element. That is why your final output displays only the last value entered in every element. You need to get rid of that for loop completely.
Try something more like this instead (there are several other problems with your code, but I'll leave those as separate exercises for you to figure out):
class Grade
{
public:
...
int size = 0;
double* grades = nullptr;
};
...
void GetScores(Grade &student)
{
int size = 0;
double score = 0;
cout << "How many test scores would you like to enter for ID# " << student.studentID << "? ";
cin >> size;
if (student.size != size) {
delete[] student.grades;
student.grades = new double[size]{0};
student.size = size;
}
for(int i = 0; i < size; ++i) {
cout << "Enter a grade: ";
cin >> score;
student.grades[i] = score;
}
for (int i = 0; i < size; ++i) {
cout << student.grades[i] << " ";
}
}
Alternatively:
#include <vector>
...
class Grade
{
public:
...
vector<double> grades;
};
...
void GetScores(Grade &student)
{
size_t size = 0;
double score = 0;
cout << "How many test scores would you like to enter for ID# " << student.studentID << "? ";
cin >> size;
student.grades.resize(size);
for (size_t i = 0; i < size; ++i) {
cout << "Enter a grade: ";
cin >> score;
student.grades[i] = score;
}
/* alternatively:
student.grades.clear();
for (size_t i = 0; i < size; ++i) {
cout << "Enter a grade: ";
cin >> score;
student.grades.push_back(score);
}
*/
for (size_t i = 0; i < size; ++i) {
cout << student.grades[i] << " ";
}
}
I removed my for loop from my while loop.
void GetScores(Grade &student)
{
int count = 0;
double score = 0;
cout << "How many test scores would you like to enter for ID# "
<< student.studentID << "? ";
cin >> student.size;
while (count != student.size) {
cout << "Enter a grade: ";
cin >> score;
student.grades[count] = score;
count++;
}
for (int j = 0; j < student.size; j++) {
cout << student.grades[j] << " ";
}
}

C++ POINTERS (student * [n] gives the error that array type is not assignable)

#include <iostream>
#include "student.h"
using namespace std;
int main()
{
// inputting the number of students
int n;
cout << "How many students would you like to process?" << endl;
cin >> n;
student* s[n];
string tmp;
double t;
// entering each student details
for (int i = 0; i < n; i++)
{
// dynamically allocating object
s[i] = new student();
cout << "Enter first name for student " << (i + 1) << endl;
cin >> tmp;
s[i]->setFirstName(tmp);
cout << "Enter middle name for student " << (i + 1) << endl;
cin >> tmp;
s[i]->setMiddleName(tmp);
cout << "Enter last name for student " << (i + 1) << endl;
cin >> tmp;
s[i]->setLastName(tmp);
cout << "Enter GPA for student " << (i + 1) << endl;
cin >> t;
s[i]->setGPA(t);
}
double avgGPA = 0;
// printing the student details
cout << "Students:" << endl;
cout << "---------" << endl
<< endl;
for (int i = 0; i < n; i++)
{
cout << s[i]->getFirstName() << " " << s[i]->getMiddleName() << " " << s[i]->getLastName() << " " << s[i]->getGPA() << endl;
avgGPA += s[i]->getGPA();
}
avgGPA /= n;
// printing the average GPA
cout << endl
<< "Average GPA: " << avgGPA;
// freeing the memory allocated to objects
for (int i = 0; i < n; i++)
delete s[i];
return 0;
}
Under the main function student * s [n]; says the array type is not assignable to the line.It also gives an error that the expression must contain a literal. I thought I was doing everything right, but there was an error. What is the solution to this error can anyone help?
student* s[n]; is a Variable-Length Array (VLA), which is not in the standard C++.
You should use std::vector like std::vector<student*> s(n);.
Also add #include <vector> at the beginning of your code to use that.

How to add getline in c++?

I am looking to remove the space from the name part of my assignment which allows users to put any name with or without space in my product list. for example "TV stand", I assume getline function will help me with it but I couldn't add the getline function into my main. can anyone help me with it?
#include <bits/stdc++.h>
#include <iostream>
#include <string>
using namespace std;
struct product {
char product_name;
int no_of_purchase;
int no_of_sales;
double purchase_cost;
double selling_price;
double profit_loss;
double percent_profit_loss;
string product_sales;
};
bool Compare(product P1, product P2)
{
return P1.percent_profit_loss > P2.percent_profit_loss;
}
int main()
{
int n;
cout << "Enter the number of the product:";
cin >> n;
cout << "\n";
product Products[n];
for (int i = 0; i < n; ++i) {
cout << "Enter the name of the product: ";
cin >> Products[i].product_name;
cout << "Enter the number of " << Products[i].product_name << " purchased: ";
cin >> Products[i].no_of_purchase;
cout << "Enter the number of " << Products[i].product_name << " sold: ";
cin >> Products[i].no_of_sales;
To be honest I don't understand your question but this might be helpful for you
I changed the product_name data type from char to string because the char data type is not making any sense
#include <iostream>
#include <string>
using namespace std;
struct product {
string product_name;
int no_of_purchase;
int no_of_sales;
double purchase_cost;
double selling_price;
double profit_loss;
double percent_profit_loss;
string product_sales;
};
bool Compare(product P1, product P2)
{
return P1.percent_profit_loss > P2.percent_profit_loss;
}
int main()
{
int n;
cout << "Enter the number of the product:";
cin >> n;
cin.ignore();
cout << "\n";
product Products[n];
for (int i = 0; i < n; ++i) {
cout << "Enter the name of the product: ";
getline(cin, Products[i].product_name);
cout << "Enter the number of " << Products[i].product_name << " purchased: ";
cin >> Products[i].no_of_purchase;
cout << "Enter the number of " << Products[i].product_name << " sold: ";
getline(cin, Products[i].no_of_sales);
cin.ignore();
}
return 0;
}

organizing array from least to greatest c++

Hi I'm working on a project that lets the user input numbers and the code organizes them in order of least to greatest and tells how many of each number was input. I'm having problems with the organizing of least to greatest and counting how many of each number are inputed
using namespace std;
#include <iostream>
void main(){
double a[30];
double e[30];
double b;
int c[30];
int d;
double f=0;
cout << "how many input values [max 30]:";
cin >> d;
cout << "enter " << d << " numbers:"<<endl;
for(int x=0; x<d;x++){
cin >> a[x];
c[x]=0;
}
cout << endl;
for(int y=0; y<d;y++){
if(a[y]>=f){
f=a[y];
}
}
for(int z=0;z<d;z++){
if(a[z]){
c[z]++;
}
if(a[z]>=a[z+1]){
e[z]=a[z];
}
}
cout << "numbers count"<< endl;
for(int printloop=0;printloop<d;printloop++){
if(a[printloop]>0){
cout << e[printloop]<< " " << c[printloop] << endl;
}
}
cout << "max value:" << b << endl;
}
Solution base on std::map http://en.cppreference.com/w/cpp/container/map, note the Compare template argument and C++11 (http://en.cppreference.com/w/cpp/language/range-for)
#include <iostream>
#include <map>
int main(int argc, char** argv)
{
std::map<int, int> count;
int n;
std::cout << "How many numbers ? ";
std::cin >> n;
std::cout << "Now enter " << n << " numbers : ";
for(auto i=0; i<n; i++)
{
int tmp;
std::cin >> tmp;
count[tmp]++;
}
for(auto const& elem : count )
std::cout << "Element " << elem.first << " count : " << elem.second << "\n";
return 0;
}

How to add a name field for a shop database (OOP/C++)

Ok, so I've made a database type program and created an item number and price field. I've also tried to stick to a primary key by using the index values of the array of both the "item number" field and "price". But was wondering how to add an "Item name" field along with this to make it work. I've tried to think of many different ways of adding a char type array but that doesn't really work.
#include<iostream>
using namespace std;
class shop
{
private:
int i,n, item[20];
float price[20];
public:
void input();
void output();
};
void shop::input()
{
cout<<"Enter the number of items: ";
cin>>n;
for (i = 1; i <= n; i++)
{
cout << "Enter the item number of the " << i << " item: ";
cin >> item[i];
cout << "Enter the price of the item: ";
cin >> price[i];
}
}
void shop::output()
{
for (i = 1; i <= n; i++)
{
cout << "Item Number: " << item[i] << endl;
cout << "Price: " << price[i] << endl << endl;
}
}
void main()
{
class shop s;
s.input();
s.output();
}
Create a class or struct to hold the data:
struct Item
{
int id;
float price; // float may lead to rounding errors.
// I would use int and store cents
//string name;
// If you really want to use c-style string
char name[20];
// or
// char *name; // You would need to use new with this
};
Then keep an array of these:
class shop
{
private:
Item items[20];
// As mentioned, better than a static array would be a vector
//std::vector<Item> items;
public:
void input();
void output();
};
What about a vector of strings?
#include<iostream>
#include <string>
#include <vector>
using namespace std;
class shop
{
private:
int i,n, item[20];
float price[20];
vector<string> names;
public:
void input();
void output();
};
void shop::input()
{
cout<<"Enter the number of items: ";
cin>>n;
names.resize(n);
for (i = 1; i <= n; i++)
{
cout << "Enter the item number of the " << i << " item: ";
cin >> item[i];
cout << "Enter the price of the item: ";
cin >> price[i];
cout << "Enter the name of the item: ";
cin >> names[i];
}
}
void shop::output()
{
for (i = 1; i <= n; i++)
{
cout << "Item Number: " << item[i] << endl;
cout << "Price: " << price[i] << endl << endl;
cout << "Name: " << names[i] << endl << endl;
}
}
And it would be good to have a destructor to clean the memory taken by the vector.
I would use std::string
#include <iostream>
#include <string>
using namespace std;
class shop
{
private:
int i,n, item[20];
float price[20];
string name[20];
public:
void input();
void output();
};
void shop::input()
{
cout<<"Enter the number of items: ";
cin>>n;
for (i = 1; i <= n; i++)
{
cout << "Enter the item number of the " << i << " item: ";
cin >> item[i];
cout << "Enter the name of the item: ";
cin >> name[i];
cout << "Enter the price of the item: ";
cin >> price[i];
}
}
void shop::output()
{
for (i = 1; i <= n; i++)
{
cout << "Item Number: " << item[i] << endl;
cout << "Item Name: " << name[i] << endl;
cout << "Price: " << price[i] << endl << endl;
}
}
int main()
{
class shop s;
s.input();
s.output();
}