I'm trying to build a little task using C++ in which I need to allow the user to determine up front how many gross_paychecks they would like to place in a vector called 'gross_paychecks_vector'.
So far this is what I have:
vector<double> gross_paychecks_vector (5);
double gross_paychecks;
// Add 5 doubles to vector
cout << "Please enter an integer" << endl;
cin >> gross_paychecks;
for(gross_paychecks = 0; gross_paychecks <= gross_paychecks_vector; ++gross_paychecks ){
cin >> gross_paychecks;
}
Right now I'm somewhat lost because I'm not sure whether to switch the vector to something like vector<double> gross_paychecks {} because it throws an error in the for loop.
Also I'm not sure how to go with the for loop (should I actually use a for-loop or something else?). I need to accept input from the user as long as it has not met the numbers of gross_paychecks that he/she has specified.
You probably want this:
vector<double> gross_paychecks_vector; // initially the vector is empty
...
cout << "How many paychecks:" << endl;
cin >> gross_paychecks;
for (int i = 0; i < gross_paychecks; i++)
{
double value;
cin >> value;
gross_paychecks_vector.push_back(value); // add new value to vector
}
// display values in vector
for (auto & value : gross_paychecks_vector)
{
cout << value << "\n";
}
Additionally. If you want to use modern C++ features, you would use:
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
int main()
{
std::vector<double> grossPaychecks{};
std::cout << "How many paychecks:\n";
size_t numberOfPaychecks{0};
std::cin >> numberOfPaychecks;
// Read all data
std::copy_n(std::istream_iterator<double>(std::cin),numberOfPaychecks, std::back_inserter(grossPaychecks));
// Print all data
std::copy(grossPaychecks.begin(), grossPaychecks.end(), std::ostream_iterator<double>(std::cout,"\n"));
return 0;
}
Related
I'm creating a console timetable application in which you can create a timetable, change it, and delete it. I'm on the stage of taking the input for the calculator. However, when I run the code, as soon as I finish taking the input, the window just closes. Here is the code:
int input()
{
int numberOfElements;
cout << "How many items do you want in your timetable? ";
cin >> numberOfElements;
char* itemArray[numberOfElements] = {};
for (int i = 1; i <= numberOfElements; i++)
{
cout << "Please enter a session: ";
cin >> itemArray[i];
}
for (int i = 0; i < numberOfElements; i++)
{
cout << itemArray[i] << "\n";
}
return 0;
}
There is some code in the main function as well, but it's irrelevant (only to find out for what day it is). I want you to have a look at the first for loop in the code, where I take in input. When running this code (in a separate window altogether), it closes as soon as I give in the input. Even if I say that I want 3 sessions (or any number), it closes right after I input the first session. In case you were wondering, I already tried replacing
char* itemArray[numberOfElements] = {};
with
char* itemArray[numberOfElements];
Just in case it's useful to anyone, I'm using the MinGW compiler.
Thanks.
In Standard C++ the size of an array must be a compile time constant. So take for example the following statements in your program:
int numberOfElements;
cout << "How many items do you want in your timetable? ";
cin >> numberOfElements;
char* itemArray[numberOfElements] = {};//not standard C++
The statement char* itemArray[numberOfElements] = {}; is not standard C++ because numberOfElements is not a constant expression.
Additionally, you're going out of bounds of the array because of the <= in the for loop instead of <. This leads to undefined behavior.
Better would be to use std::vector<std::string> as shown below:
#include <iostream>
#include<vector>
#include <string>
int main()
{
int numberOfElements;
std::cout << "How many items do you want in your timetable? ";
std::cin >> numberOfElements;
std::vector<std::string> arr(numberOfElements); //create vector of size numberOfElements
for (std::string &element: arr)
{
std::cout << "Please enter the element: ";
std::cin >> element;
}
for (const std::string& element: arr)
{
std::cout << element << "\n";
}
}
Demo.
I was practicing with vector, I wanted to push an element using push_back(); using a for loop, but the program doesn't even enter the for loop, help!!!
#include <iostream>
#include <vector>
using namespace std;
int main()
{
cout << "check ";
int val;
vector<char> vec;
cout << "check " << endl << "Its in the game";
//those two "check" were to confirm if the program is even running and is it a
problem while declaring the vector
for(int i = 0; i < vec.size(); i++){
cout << "enter element for vector" << endl;
cin >> val;
vec.push_back(val);
}
}
Your vector is empty. The for loop starts at zero, which is not less than zero, so the for loop never runs.
Your vector is literally empty, which means vec.size() is 0.So It will never enter the loop. If you know what your vector size is gonna be, you should define it as
std::vector<int> vec(vec_size);
for(int i=0;i<vec_size;++i)
{
//whatever.....
}
Or you could have used a while loop.
while(std::cin>>val)
{
//do your thing....
}
Currently working on an exercise from Stroustrup's intro to C++ book and it asks: Write a function that given two vectors price and weight computes a value (an “index”) that is the sum of all price[i]*weight[i]. Make sure to have weight.size()==price.size()
vector<double> weight;
vector<double> price;
void read_weight() {
cout << "Input weight" << '\n';
for (double weights; cin >> weights; ) {
weight.push_back(weights);
if (!(cin >> weights)) {
cin.clear();
cin.ignore(numeric_limits<double>::max(), '\n' );
break;
}
}
}
void read_price() {
cout << "Input price" << '\n';
for (double prices; cin >> prices; ) {
price.push_back(prices);
if (!( cin >> prices)) {
cin.clear();
cin.ignore( numeric_limits<double>::max(), '\n' );
break;
}
}
}
void calculate() {
double sum = 0;
for (int i = 0; i < price.size(); ++i)
sum += price[i] * weight[i];
cout << "Sum is " << sum << '\n';
}
int main() {
read_weight();
read_price();
calculate();
}
This is the code I currently have, but I cannot figure out how to terminate input properly. In previous chapters, his book mentions you could use an input besides a double to terminate (like |). However, I learned that this only puts cin into the failed state and does not allow me to move onto the price function. Unfortunately, the book does not cover how to handle this as of yet so I just copied code about cin.clear and cin.ignore in hopes that it would work. But this did nothing. I noticed that I was actually allowed a single input if I were to change the vector to int instead of double and am perplexed for the difference in behavior. I was wondering if anyone could give me tips on how to fix this?
You were halfway there already. I've written a commented replacement for read_weights(); you should be able to take it from there.
#include <vector>
#include <limits>
#include <iostream>
// Use return values instead of working on global variables.
// Avoid using global variables whenever possible, they are a
// maintenance pain.
std::vector< double > read_weights()
{
std::vector< double > weights;
double weight;
// You can embed the \n right in the string, no need to put it as a
// separate character.
std::cout << "Input weights; enter a non-number to terminate input.\n";
// If anything not double is entered, cin goes into fail state --
// that is our terminating condition right there, so use it!
while ( std::cin >> weight )
{
weights.push_back( weight );
}
// Clean up cin
std::cin.clear();
// Use the correct type for max(); you had 'double' here...
cin.ignore( numeric_limits< std::streamsize >::max(), '\n' );
// Don't worry about the apparent copying of the vector upon return.
// Any modern compiler should be able to optimize this away.
return weigths;
}
A simple main() for testing:
int main()
{
std::vector< double > weights = read_weights();
std::cout << "Vector contents:\n";
for ( auto & v : weights )
{
std::cout << v << "\n";
}
}
Now all you have to add is a read_price()... now wait, you don't, do you? Because all you're actually doing is the very same thing as in read_weights(), entering doubles! So move the input prompt out of read_weights() and make it one function, read_values(), which you call twice, once to get weights and once to get prices...
int main()
{
std::cout << "Enter weights; enter a non-number to terminate input.\n";
std::vector< double > weights = read_values();
std::cout << "Enter prices; enter a non-number to terminate input.\n";
std::vector< double > prices = read_values();
// ...
}
For the calculate function, use references for the parameters so the vectors don't have to be copied:
void calculate( std::vector<double> & weights, std::vector<double> & prices )
And once you got this all running, keep in your mind that, later on, you will (or at least should) be learning about <algorithm>, functors, and lambdas... which should remove the need for calculate and replace it with an elegant one-liner... but that's yet to come, and I don't want to confuse you with that at this point.
You can use std::getline to read a whole line from cin into a string. Thereafter, you need to determine whether the line that has been entered is a double or not. I normally wouldn't recommend going too wild with regular expressions (I don't use them a lot in C++), but in this case I reckon it is a pretty simple and sound solution. If the string is in the format "32.23" (digits dot digits), you convert it to a double using std::stod, push that to the vector and continue to read from cin. If it is not, you break the loop and go on with the program flow.
Stay away from using global variables, use local ones and pass them arround.
Also, notice that your functions read_price and read_weight are almost identical. In such a case, you definitely only want to write a single (parameterized) function. In this case, you don't even need parameters, you can just use the same function for both.
(You could also directly read your values into double variables from a stream (std::cin), which might be considered more elegant as you need less conversion, however the method below is easy and you don't need to worry what is being entered into std::cin)
#include <vector>
#include <string>
#include <iostream>
#include <regex>
std::vector<double> get_doubles_from_cin(){
std::vector<double> doubles;
std::regex double_regex ("\\d+\\.\\d+");
std::string input;
while(std::getline(std::cin, input)){
if (std::regex_match(input, double_regex)){
doubles.push_back(std::stod(input));
}
else{
break;
}
}
return doubles;
}
void calculate(std::vector<double>& weights, std::vector<double>& prices) {
double sum = 0;
for (int i = 0; i < prices.size(); ++i) {
sum += weights[i] * prices[i];
}
std::cout << "Sum is " << sum << '\n';
}
int main() {
std::cout << "Enter weights" << std::endl;
auto weights = get_doubles_from_cin();
std::cout << "Enter prices" << std::endl;
auto prices = get_doubles_from_cin();
calculate(weights, prices);
}
My question is pretty specific, I think. My program is supposed to store 10 names, and their corresponding phone numbers into an array. I want to sort the names/numbers by phone numbers, ascending order, and then output the array in the sorted order. Thanks for the help! Any and all help is appreciated.
What I have so far:
using namespace std;
main()
{
string name[10][2];
int x;
cout << "Please input 10 names";
for(int i = 0; i < 10; i++){
cin >> name[i][x];
}
int i = 0;
cout << "Please input their corresponding numbers";
for(x = 0; x < 10; x++){
cin >> name[i][x];
}
}
EDIT: Would it be possible(not as hassling) to instead do this but with a parallel array storing a string(name) and an int(number) and sort it by the int?(Of course, while keeping the names by their corresponding number) If so, how could I change it from a two-dimensional to a parallel array?(Or just pointing me in the right direction would be greatly appreciated) :)
You will want to use a vector of pairs. This is in this case more convenient than a map because you want to sort by value rather than by key. There are also methods to sort a map by value (see question Sorting std::map using value), but for this purpose a vector of pairs seems appropriate.
If you want to have a constant memory array instead of a dynamic memory array (std::vector) then use std::array<std::pair<std::string,int>, N>, where N is the number of elements.
Needs C++14 because of the template lambda.
#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
int main()
{
std::vector<std::pair<std::string,int>> phonebook;
phonebook.reserve(10);
std::cout << "Please input a name and a number\n";
for (int i = 0; i < 10; ++i) {
std::cout << "Name: ";
std::string name;
std::cin >> name;
std::cout << "Number: ";
int number;
std::cin >> number;
phonebook.push_back({name, number});
}
std::sort( std::begin(phonebook),
std::end(phonebook),
[] (auto a, auto b) { return a.second < b.second; });
for (auto const& entry : phonebook)
{
std::cout << entry.first << ' ' << entry.second << '\n';
}
}
I'm new to programming (in general) and C++ (in particular). I'm learning vectors and am trying to write a simple program that:
allows the user to enter a vector of students' test scores
when the user types the sentinel (-1 in this case), the vector terminates
outputs a tally of the student's grades
Here's my code:
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
const int SENTINEL = -1;
vector<int> studentGrades = { 0 };
int myInput;
int main()
{
do
{
cout << "Please enter a student's grade: ";
cin >> myInput;
if (myInput < 1000)
{
studentGrades[myInput]++;
}
studentGrades.push_back(myInput);
} while (myInput != SENTINEL);
cout << "\n";
for (int i = 0; i < 1000; i++)
cout << i << " grade(s) of " << studentGrades[i] << endl;
return 0;
}
Two questions:
1) Can anyone provide guidance on why this code is only allowing me to enter one student's grade?
2) Is the for loop that compute the "tally" correct?
Thanks in advance for taking a look,
Ryan
* REVISED CODE *
# JCx - this is the revised code:
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
const int SENTINEL = -1;
vector<int> studentGrades = { 0 };
int myInput;
int main()
{
do
{
cout << "Please enter a student's grade (or -1 to QUIT): ";
cin >> myInput;
if (myInput < 1000)
{
studentGrades.at(myInput)++;
}
studentGrades.push_back(myInput);
} while (myInput != SENTINEL);
cout << "\n";
for (int i = 0; i < 1000; i++)
cout << i << " grade(s) of " << studentGrades.at(myInput) << endl;
return 0;
}
and, I'm seeing this error:
Unhandled exception at 0x7707C42D
Microsoft C++ exception: std::out_of_range at memory location 0x0035F890
There's more than one problem. The attempt to access studentGrades[-1] when the users enters your sentinel value, and the fact that the default vector only contains an entry for 0 and the use of push_back.
Let's just walk through some of the problems:
User runs program. User enters 100. studentGrades[100] is out of range. Undefined behaviour occurs as the vector only has one element.
User runs program, enters -1 studentGrades[-1] is out of range.
User runs program, enters 0. studentGrades[0] is in range, incremented to 1. studentGrades.push_back(1) adds an element to the vector studentGrades[1] is now also equal to 1.
As a great starting point, if you swap your subscript vector references for the vector at method as I've shown below you will get out-of-range errors which will help (a lot). The code below still needs work but at least you'll have run-time errors instead of odd behaviour.
int main()
{
do
{
cout << "Please enter a student's grade: ";
cin >> myInput;
if (myInput < 1000)
{
studentGrades.at(myInput)++;
}
studentGrades.push_back(myInput);
} while (myInput != SENTINEL);
cout << "\n";
for (int i = 0; i < 1000; i++)
cout << i << " grade(s) of " << studentGrades.at(myInput) << endl;
return 0;
}
I think if I was implementing this I'd be using std::map instead of a vector. It would let you have a studentGrade[1000] without having to allocate memory for studentGrade[0] to [999] first.
However as you are learning about std::vector check out vector::resize to set the vector big enough for the required elements, std::vector::size to find out whether you need to increase the size. You could then ditch the push_back.
References
vector::at http://www.cplusplus.com/reference/vector/vector/at/
vector::size http://www.cplusplus.com/reference/vector/vector/size/