I want to enter names, student numbers and student scores and display this information.
I used arrays in this way:
#include "stdafx.h"
#include <iostream>
#include <string>
#define size 3
using namespace std;
class student{
public:
void vrod();
void dis();
int stno,score,i,n;
};
void student::vrod(){
cout<<"name=";
cin>>name;
cout<<"stno=";
cin>>stno;
cout<<"score=";
cin>>score;
}
void student::dis(){
cout<<"name="<<name<<"\n"<<"stno="<<stno<<"\n"<<"score="<<score<<"\n";
}
int main(){
int i, j=0,n,;
string h;
student st[size];
while (j<3){
st[j].vrod();
j++;}
j=0;
while (j<3){
st[j].dis();
j++;}
cin.get();
cin.get();
}
According to recommendation of my friends, I used vector in this way:
#include "stdafx.h"
#include<iostream>
#include<vector>
#include<sstream>
#include<string>
#define n 3
using namespace std;
int main()
{
int input;
string names;
vector<int> stno,score;
vector<string> name;
cout<<"Enter the number of inputs: ";
cout << "Enter your numbers to be evaluated: " << endl;
for(int i=0;i<n;i++){
cout<<"student No.=";
cin >> input;
stno.push_back(input);
}
for(int i=0;i<n;i++){
cout<<"scor=";
cin >> input;
score.push_back(input);
}
for(int i=0;i<n;i++){
cout<<"name=";
cin >> names;
name.push_back(names);
}
for(int i=0;i<stno.size();i++)
cout<<stno[i];
for(int i=0;i<score.size();i++)
cout<<score[i];
for(int i=0;i<name.size();i++)
cout<<name[i];
cin.get();
cin.get();
}
Do you have any opinion to improve the second code written via vector? Can I save information from one student including student numbers and student scores in one position in vector like arrays? I mean for example if my n is 3, I enter the information of students in three positions like arrays(student st[size];)
Can I save information from one student including student numbers and
student scores in one position in vector like arrays? I mean for
example if my n is 3, I enter the information of students in three
positions like arrays(student st[size];)
Yes you can. A std::vector is a dynamic array that expands. So you could do something like this...
std::vector<student> my_vector;
for(int i = 0; i < n; i++)
{
student new_student;
cout << "Number: "
cin >> new_student.number;
cout << "Score: "
cin >> new_student.score;
cout << "Name: "
cin >> new_student.name;
my_vector.push_back(new_student);
}
//Accessing
std::cout << "Hello my name is: " + my_vector[0].name;
//Setting
vector[0].name = "Cranky Kong";
std::cout << "Hello my name is: " + my_vector[0].name;
Related
I was given a C++ assignment for my class to make a program that reads student data records from a user, and the program will then sort the keyed in data records into sorted order in terms of students’ GPAs, or in terms of the alphabetical order of the students' last names, or doing both, depending on the user’s option. The framework was given to me by my professor.
I'm having difficulties with vectors and strings, and getting these to work in my given program. I keep receiving the following errors:
no matching function for call to ‘std::vector::push_back(std::string&)’
no matching function for call to ‘std::vector::push_back(float&)’
I've included my full code below and would greatly appreciate if somebody could give it a look. I understand that something needs to be changed for v.push_back(); to work, but I'm not sure about the exact change I should make. I'm very new to C++ and have a limited understanding of strings and vectors.
Thank you so much in advance!
#include <iostream>
#include <cctype>
#include <string>
#include <cstring>
#include <vector>
using namespace std;
struct student
{
string name;
float gpa;
};
std::vector <student> v;
void input_data(std::vector<student> &v);
void output_data();
void swap(student *std1, student *std2);
void sort_gpa_asc();
void sort_gpa_des();
void sort_name();
void show_data();
int num;
int main()
{
char option;
v.push_back(student{"Dana", 3.6});
input_data(v);
cout << "Your options for sorting (key in 'G' to sort students' data in terms of gpa in" << endl
<< "both ascending and descending order; key in 'A' to sort students' data in terms of" << endl
<< "alphabetical order of students' last name; key in 'B' for both types of sorting): ";
cin >> option;
int num;
if (option == 'G')
{
sort_gpa_asc();
sort_gpa_des();
}
else if (option == 'A')
{
sort_name();
}
else if (option == 'B')
{
sort_gpa_asc();
sort_gpa_des();
sort_name();
}
else
cout << "Incorrect option!" << endl;
return 0;
}
void input_data(std::vector<student> &v)
{
string names;
float grade_point_average;
int num;
v.push_back(student{"Dana", 3.6});
cout << "Enter the number of students: ";
cin >> num;
for(int i=0; i < num; i++){
cout << "Enter student's name (write the surname before the first name): ";
cin.get();
getline(cin, names);
v.push_back(names);
}
for(int i=0; i < num; i++){
cout << "Enter student's GPA: ";
cin >> grade_point_average;
v.push_back(grade_point_average);
}
for(int i=0; i < v.size(); i++){
cout << v[i].gpa;
}
for(int i=0; i < v.size(); i++){
cout << v[i].name;
}
cin.get();
cin.get();
}
void swap(student *std1, student *std2)
{
}
void sort_gpa_asc()
{
}
void sort_gpa_des()
{
}
void sort_name()
{
}
void show_data()
{
}
Your vector has a type std::vector<student>
But you are trying to push a string instead:
string names;
v.push_back(names);
You probably meant v.push_back(student{names, 0});
This however opens another issue with pushing the GPA. Here you should just iterate over existing elements:
for(int i=0; i < num; i++){
cout << "Enter student's GPA: ";
cin >> grade_point_average;
v[i].gpa = grade_point_average;
}
I would also advise you to use emplace_back instead of push_back as a more efficient alternative:
//v.push_back(student{"Dana", 3.6});
v.emplace_back("Dana", 3.6);
you can use vector::push_back requires the template type of your vector in you case
vector<student>::push_back(student);
the code you should use is something like this
v.push_back(student(constructor arguments))
or
student s = {.name = "name", .gpa = x};
v.push_back(s);
i think the vector v is type student, but not string or float, thus it occurs error.
Here's my code:
int amount;
cout<<"How many books are you donating? ";
cin>>amount;
string donation[amount];
cout<<"Enter the titles:"<<endl;
for (int i=0; i<amount; i+=1)
{
getline(cin.ignore(numeric_limits<streamsize>::max(), '\n'), donation[i]);
}
cout<<endl<<"You donated these:";
for (int j=0; j<amount; j+=1)
{
cout<<donation[j]<<endl;
}
This accepts 5 values even though I only input 3 for amount. Then it prints only values 1, 3, and 5.
If I just write it as getline(cin.ignore(), donation[i]); or getline(cin.ignore(1, '\n'), donation[i]);, then the output becomes like this:
How many books are you donating? 3
Enter the titles:
book1
book2
book3
You donated these:
book1
ook2
ook3
What should I write in the cin.ignore() for it to ignore just the \n value?
You need to discard the \n after the first cin>>amount read,
note: instead of i+=1 it you can use either i++ or ++i (is a more standard way)
#include <iostream>
#include <string>
#include <limits>
using namespace std;
int main()
{
int amount;
cout<<"How many books are you donating? ";
cin>>amount;
string donation[amount];
cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
cout<<"Enter the titles:"<<endl;
for (int i=0; i<amount; i++)
{
cout<< "Enter title "<<i << ":";
getline(cin, donation[i]);
}
cout<<endl<<"You donated these:"<<endl;
for (int j=0; j<amount; j++)
{
cout<<donation[j]<<endl;
}
return 0;
}
Array size must be a fixed compile-time constant. Dynamically determining its size at runtime by the value you input to amount is not valid C++, as pointed out by Paul.
Use a std::vector of std::string type for donation instead:
#include <iostream>
#include <vector>
int main()
{
int amount;
std::cout<< "How many books are you donating? ";
std::cin>> amount;
std::vector<std::string> donation;
std::string title;
std::cout<< "Enter the titles: \n";
for (int i=0; i<amount; i+=1)
{
std::cin>> title;
donation.push_back(title);
}
std::cout<< "You donated these: \n";
for(auto x:donation)
std::cout<< x << "\n";
}
I am trying to create a program that will draw using a single dimensional array however I am having a hard time initializing the array using only one cin statement. A sample input that the user in supposed to look like
1<space>2<space>34<space>3<space>2<space>1<space>0<space>10
#include<iostream>
using namespace std;
/*---------------------------------------------------------------------------------------
Prototypes
These are the prototype function(s) that will be used to to draw the row and columns
---------------------------------------------------------------------------------------*/
void draw(int nums);
//---------------------------------------------------------------------------------------
int main(){
const int MAX = 100;
int chart[MAX];
int nums;
cout << "Enter numbers for the chart" << endl;
cin >> nums;
draw(nums);
return 0;
}
void draw(int nums) {
cout << endl;
int row;
for (row = 0; row < nums; ++row) {
cout << "*" << endl;
}
}
How would I initialize the array with the sample input given and then pass it to a function to be used to draw
Here's a simple (perhaps unsafe but then again don't use std::cin for safety) implementation that seems to work for reading in the numbers:
#include <iostream>
#include <list>
#include <sstream>
int main()
{
std::cout << "Input numbers: ";
// get input line
std::string input;
std::getline(std::cin, input);
std::stringstream ss(input);
// read numbers
std::list<int> numbers;
while(ss) {
int number;
ss >> number;
ss.ignore();
numbers.push_back(number);
}
// display input
for(const auto number: numbers) {
std::cout << number << std::endl;
}
return 0;
}
And here's a sample run:
$ ./a.out
Input numbers: 1 2 3 4
1
2
3
4
I think you need a parse to decode the input. something like following:
void parse(const std::string& input, int output[], int MaxNum)
{
// parse the integer from the string to output.
}
int main(){
......
std::string input;
cout << "Enter numbers for the chart" << endl;
cin >> input;
parse(input, chart, MAX);
......
}
Here is a version of a program that lets you input a series of numbers with only one cin line with the help of stringstream, but the only difference is that it stores the input in a vector. It then draws a histogram chart based on the input.
Just press the <ENTER> key twice to let the program know that you are done with the inputting of the numbers.
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <sstream>
using namespace std;
vector<int> Vector;
string line;
void drawchart(int max);
int main() {
cout<<"Chart drawing program ( Histogram) \n";
cout<<"Enter a series of numbers. \n";
cout<<"Seperate with a space, press <ENTER> TWICE to end input \n";
cout<<" (e.g 2 3 4 5 6) > ";
if(!getline(cin, line)) return 1;
istringstream iss(line);
copy( istream_iterator<int>(iss), istream_iterator<int>(), back_inserter(Vector));
copy(Vector.begin(), Vector.end(), ostream_iterator<int>(cout, ", "));
cout<<"\nDrawing chart.. \n\n";
drawchart( Vector.size() );
cout<<"Press ANY key to close.\n\n";
cin.ignore();cin.get();
return 0;
}
// draws a chart or hjistogram
void drawchart(int max){
for( int i = 0; i < max ; i++){
for(int j = 0; j < Vector[i]; j++) cout << "*";
cout << endl;
}
}
So I want the user to input something like this:
0 15 72 34 92 8
and I want to fill a vector of integers with these numbers.
Here is what I have:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> V;
cout << "Please enter the numbers separated by \n";
cout << "spaces, then press the \"Enter\" key.\n\n";
int temp;
while (cin >> temp)
{
V.push_back(temp);
}
// The programs gets to this point and continuously asks for input
// Print the vector
cout << "The vector contains [ ";
for(int i = 0; i < V.size(); i++)
cout << V.at(i) << " ";
cout << "], ";
}
Modify your code based on this example. It takes input from user until user enters -1.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int number;
vector<int> userInput;
do
{
cout << "Enter a number (-1 to quit): ";
cin >> number;
userInput.push_back(number);
} while (number != -1);
for (vector < int >::iterator it = userInput.begin(); it < userInput.end() - 1; it++)
{
cout << endl << *it;
}
system("pause");
return 0;
}
First, read the entire line as a string using getline and after that fetch every integer and push it into the integer array.
vector<int> v;
string buffer;
int data;
getline(cin, buffer);
istringstream iss(buffer);
while (iss >> data)
v.push_back(data);
One column for student, and one column for marks.
I have researched a lot for this but still the code isnt working.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string arr[2][2];
for (int i=0; i<2; i++)
{
for (int j=0; j<2; j++)
{
cout<<"Enter name: "<<(i+1)<<endl;
cin>>arr[i][0];
cout<<"Enter marks: "<<(i+1)<<endl;
cin>>arr[i][1];
}
}
cout<<arr[0][0]<<"\t\t";
cout<<arr[0][1]<<endl;
cout<<arr[1][0]<<"\t\t";
cout<<arr[1][1]<<endl;
return 0;
}
When i enter data, i get to insert 8 elements instead of 4. It's a 2x2 table.
Think about your double for loop. You are going:
i: 0
j: 0
i: 0
j: 1
i: 1
j: 0 etc..
Yes this is 4 but each time you take 2x user input.
Try this:
for (int i=0; i<2; i++)
{
cout<<"Enter name: "<<(i+1)<<endl;
cin>>arr[i][0];
cout<<"Enter marks: "<<(i+1)<<endl;
cin>>arr[i][1];
}
I mean you are not even using j in the loop? As a fun addition, think about using a different type for your storage of user and mark. I think that you would be better off with a map:
std::map<string, int> gradeRegister;
for (int i=0; i<2; i++)
{
string name;
int grade;
cout << "Enter name " << i+1 << ": " << std::flush;
cin >> name;
cout << "Enter grade " << i+1 << ": " << std::flush;
cin >> grade;
gradeRegister[name] = grade;
}
Maps make a lot more sense in this situation because then you will have a unique name to grade, its easy to search and you can expand it to contain many more people much more easily. Take a look here for more information.
Although you can ask for values, a more user friendly method is to input all the marks for a single user before asking for all the marks for another user.
(The following code assumes one student can have multiple marks and student names are unique):
#define MAXIMUM_STUDENTS 3
#define MAXIMUM_MARKS_PER_STUDENT 4
typedef std::vector<std::string> Marks_Container;
typedef std::map<std::string, Marks_Container> Registry_Container;
Registry_Container student_registry;
for (int student = 0; student < MAXIMUM_STUDENTS; student++)
{
cout<<"Enter student name name: " << endl;
std::string student_name;
getline(cin, student_name);
Marks_Container student_marks(MAXIMUM_MARKS_PER_STUDENT);
for (int mark_index = 0;
mark_index < MAXIMUM_MARKS_PER_STUDENT;
++mark_index)
{
cout << "Enter mark "
<< (mark_index + 1)
<< ": " << endl;
std::string mark;
getline(cin, mark);
student_marks.push_back(mark);
}
student_registry[student_name] = student_marks;
}
There is no reason to duplicate student names, which is the reason for the std::map<name, marks> structure. The key field is the student name and the value field is a vector of marks.