C++ Pointer Array Won't Accept More Values - c++

please, why this pointer array won't accept more than 5 values?
Doing excercises from Prata's C++ book, but got stuck on this.
//ex2_numrow -- showing entered numbers til zero is entered
#include <iostream>
using namespace std;
int main()
{
int n = 0;
int num = 0;
int* entered = new int[1];
do
{
cout << "Enter number: ";
cin >> num;
entered[n] = num;
cout << "Your numbers: ";
for (int i = 0; i <= n; i++)
{
cout << entered[i] << " ";
}
cout << endl << endl;
n++;
} while (num);
delete[] entered;
return 0;
}

The code int* entered = new int[1]; gives you a pointer to an array of size one!
It is very unwise (i.e., undefined behaviour) to then try to write values outside of that array. The best case is that your code will crash before it causes any serious issues.
As an aside, the set of use cases for raw pointers is fast dwindling in C++, you should generally be looking at smart pointers instead.
I say "generally" because, if your intent is to have a resizable array, even smart pointers won't help that much. What will help is a little thing I like to call std::vector :-) You should probably look into using that for your immediate purpose.
For example, this program accepts positive numbers, adding them to a vector, then printing them out:
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers;
int num;
do {
std::cout << "Enter number: ";
std::cin >> num; // should probably check for errors in real code
if (num >= 0) {
numbers.push_back(num);
}
} while (num >= 0);
std::cout << "You entered:";
for (int num: numbers) {
std::cout << ' ' << num;
}
std::cout << '\n';
}

Related

Passing dynamic arrays to recieve inputs in separate functions

I would like to pass dynamic arrays to functions and receive user input. Currently I'm using the following code:
#include <iostream>
using namespace std;
struct make
{
int part;
int graph;
int like;
};
int z;
int *p = new int [z];
void inpart( make x[],int *fig)
{
cout << "Input part\n";
cin >> x[*fig].part;
}
void ingraph(make x[],int *tig)
{
cout << "Input graph\n";
cin >> x[*tig].graph;
}
void inlike(make x[],int *gig)
{
cout << "Input like\n";
cin >> x[*gig].like;
}
int main()
{
cout << "Input array count\n";
cin >> z;
make p[z];
for (int i=0; i < z; i++)
{
inpart(p,&z);
ingraph(p,&z);
inlike(p,&z);
}
for (int i=0; i < z; i++)
{
cout << "the result is\n";
cout << p[z].part << ", ";
cout << p[z].graph << ", ";
cout << p[z].like << "\n";
}
}
My input 1,1,1 for all the structure objects should output 1,1,1. However, the answer I receive is 1,0,2. Why?
Firstly, you shouldn't trying to initialize a static buildin array in run-time:
Your implementation is wrong here:
cout<< "Input array count\n";
cin>>z;//initialized in run-time
make p[z]; // wrong, need to be allocated with new
make* example = new make[z]; // Ok!
Secondly, you're trying to read and write out of bounds of the created array. It's Undefined behaviour. When you're creating an array with size N, chunk of the memory will be allocated to which you can have access by index. In your case from 0 to z or [0,z), excluding z. To sum up, your cycle should look like this:
for (int i = 0; i < z; i++) {
inpart(p,&i);
ingraph(p,&i);
inlike(p,&i);
}
Actually u've made a lot of mistakes in your code, but I feel like you will understand this later when continue learning.

c++ Question with displaying text between two array variables

I always seem to have this problem when I want to display two variables of an array in one iteration of a loop, I'm wondering if there is a nicer way of displaying the array.
The code works if I change ++i to i+1 but I'm wondering why that happens, and I'm wondering if there's a smarter way to do what I want. The error says unsequenced modification and access to 'i' [-Wunsequenced]
#include <iostream>
#include <memory>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
int players = 0,rounds=0;
bool winnerFound=false;
cout << "Welcome to my tournament match maker\n";
cout << "Enter the number of participants in the tournament: ";
cin >> players;
rounds=players/2;
string *pNames = new string[players]; //dynamically allocate
for (int i = 0;i < players;i++)
{
cout << "Enter the name of player " << i + 1<<":";
cin >> pNames[i];
}
random_shuffle(&pNames[0],&pNames[players]);
for(int i=0;i<rounds;i++)
{
cout<<pNames[i]<<" vs "<<pNames[++i]; //
}
return 0;
}
I'm not sure if that's the best way to do it, any tips would be appreciated.
For the tips, I think it is better to use a STL container instead of a raw array. std::array or std::vector for example. You can change the declaration of pNames as follows:
std::vector <std::string> pNames(players);
Your problem is that you iterate only until rounds. You don't want that, you want to loop over all players, not only half of them.
To make your code work, you need to write:
for(size_t i = 0; !pNames.empty() && i < pNames.size()-1; ++i)
{
std::cout << pNames[i] << " vs " << pNames[++i] << std::endl;
}
But I think it is a bad way to modify i from inside the loop, you better have to directly increment i by two in the loop statement. This will give:
for(size_t i = 0; !pNames.empty() && i < pNames.size()-1; i+=2)
{
std::cout << pNames[i] << " vs " << pNames[i+1] << std::endl;
}
Of course, if you have only one player or any odd number of players, you will miss the last one (because you need two opponents to make a vs).
I hope it can help.
#include <iostream>
#include <memory>
#include <string>
#include <algorithm>
#include <ctime>
using namespace std;
int main()
{
srand(time(NULL));
int players = 0,count=0;
cout << "Welcome to my tournament match maker\n";
cout << "Enter the number of participants in the tournament: ";
cin >> players;
string *pArray = new string[players]; //dynamically allocate
cin.ignore();
for (int i = 0;i < players;i++)
{
cout << "Enter the name of player " << i + 1<<":";
getline(cin, pArray[i]);
}
random_shuffle(&pArray[0], &pArray[players]);
for (int i = 0;i < players;i++)
{
cout << ++count << ": " << pArray[i] << " vs " << pArray[i + 1] << endl;
i++;
}
return 0;
}
Any critiques?
Firstly i++ and ++i are different.
i++ increments after returning the value and
++i increments before returning the value of the result.
It would be more readable if you incremented your i in the for loop by two and then not have a side effect when asking for the array value. And of course you need to check if i is valid at this point
for(int i=0; i < players-1; i += 2)
{
// check if valid.
// with odd numbers of players, the last remaining player will be dropped.
cout << pNames[i]<<" vs " << pNames[i+1]; // no side effect.
// In a for loop
// all increments should happen in
// the loop header.
}

C + + Can I use arrays here to shorten my code?

This is my first post on here so please don't kill me for my noobishness.
I recently made a program for fun to put in a ton of numbers and have it put out the mean, not very useful but I thought I would see if I could. I would love it if someone could explain to me how I could improve my code using arrays instead of lots of variables, but still achieve the same thing, maybe even more efficiently.
My code looks like this:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main() {
int q1;
int q2;
int q3;
int q4;
int q5;
int q6;
int q7;
int q8;
int q9;
int q10;
int q11;
int q12;
int f;
//Used for the total of all values
int t;
//Used for the total to be divided
int a;
//Used for dividing the numbers.
cout << "We will be finding a mean. Enter the amount of numbers that will be entered, the maximum is 12: ";
cin >> a;
cout << "Now enter what numbers you want to find the mean for, because the maximum is 12, if you have less than 12, enter 0 for the rest: ";
cin >> q1;
cin >> q2;
cin >> q3;
cin >> q4;
cin >> q5;
cin >> q6;
cin >> q7;
cin >> q8;
cin >> q9;
cin >> q10;
cin >> q11;
cin >> q12;
f = q1 + q2 + q3 + q4 + q5 + q6 + q7 + q8 + q9 + q10 + q11 + q12;
cout << f / a << '\n';
system("pause");
}
Any advice is very appreciated! This was made in Visual Studio just in case you needed to know.
Of course arrays can make your life easier!
Here's how you could have accomplished the same task as above, with arrays:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main() {
int totalNums;
cout << "We will be finding a mean.\n";
cout << "You can only enter up to 12 numbers;
// Declare an array to hold 12 int's
int nums[12];
// i will count how many numbers have been entered
// sum will hold the total of all numbers
int i, sum = 0;
for(i = 0; i < 12; i++) {
cout << "Enter the next number: ";
cin >> nums[i];
sum += nums[i];
}
cout << "The mean is: " << (sum / totalNums) << '\n';
//Try to avoid using system!
system("pause");
}
But, why use an array?
There's no need to keep any of the numbers after you add them to the total, so why use an array?
You can accomplish the same task without an array and with only one variable for the numbers!
#include "stdafx.h"
#include <iostream>
using namespace std;
int main() {
int totalNums;
cout << "We will be finding a mean.\n";
cout << "Enter the amount of numbers that will be entered: ";
cin >> totalNums;
// i will count how many numbers have been entered
// sum will hold the total of all numbers
// currentNum will hold the last number entered
int i, sum = 0, currentNum = 0;
for(i = 0; i < totalNums; i++) {
cout << "Enter the next number: ";
cin >> currentNum;
sum += currentNum;
}
cout << "The mean is: " << 1.0 * sum / totalNums << '\n';
//Try to avoid using system!
system("pause");
}
Arrays can be considered as series of variables each of which has ids.
integers between 0 and (number of elements) - 1 (both inclusive) are available ids.
Using that with loop, your code can be like this (sorry, I hate stdafx.h):
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
int q[12];
int f;
//Used for the total of all values
int t;
//Used for the total to be divided
int a;
//Used for dividing the numbers.
cout << "We will be finding a mean. Enter the amount of numbers that will be entered, the maximum is 12: ";
cin >> a;
cout << "Now enter what numbers you want to find the mean for, because the maximum is 12, if you have less than 12, enter 0 for the rest: ";
for (int i = 0; i < 12; i++) {
cin >> q[i];
}
f = 0;
for (int i = 0; i < 12; i++) {
f += q[i];
}
cout << f / a << '\n';
system("pause");
}
You may use the numbers read in the future, but currently the numbers aren't used except for calculating the sum, so you can omit the array and do addition while reading. Also I deleted the variable t, which is unused and stopped using using namespace std;, which is not considered as good.
#include <cstdlib>
#include <iostream>
using std::cin;
using std::cout;
int main() {
int q;
int f;
//Used for the total of all values
int a;
//Used for dividing the numbers.
cout << "We will be finding a mean. Enter the amount of numbers that will be entered, the maximum is 12: ";
cin >> a;
cout << "Now enter what numbers you want to find the mean for, because the maximum is 12, if you have less than 12, enter 0 for the rest: ";
f = 0;
for (int i = 0; i < 12; i++) {
cin >> q;
f += q;
}
cout << f / a << '\n';
system("pause");
}
You marked this question as C++.
I recommend you do not use "using", and you should prefer vector over array.
Consider the following approach:
#include <iostream>
#include <vector>
int main(int argc, char* argv[])
{
std::cout << "We will be finding a mean." << std::endl
<< "Enter numbers, and press ^d when complete.\n"
<< std::endl;
// Declare a vector to hold user entered int's
std::vector<int> intVec;
// the vector automatically keeps track of element count
do {
std::cout << "number: "; // prompt
int t = 0;
std::cin >> t; // use std::cin,
if(std::cin.eof()) break; // ^d generates eof()
intVec.push_back(t);
}while(1);
// there are several way to sum a vec,
// this works fine:
int sum = 0;
for (auto i : intVec) sum += i;
std::cout << "\n sum : " << sum
<< "\ncount : " << intVec.size()
<< "\n mean : " << (sum / intVec.size()) << std::endl;
return(0);
}
You can enter single item per line (neatness counts).
You can enter multiple integers separated by white space, but the above will give back a prompt for the integers already entered.
^d - generates an end of file input.
... press and hold 'Control' key and letter 'd' at same time
Note - does not handle error input - try entering a 'number' as 'num' string.
The accepted answer is definitely the most efficient way to transform your code using arrays, but one thing I would add is that in C++ dividing an integer by another integer can only ever result in an integer, and because you're trying to get the mean, it seems like you'd want to have the result in decimals, so you need to do one of two things:
Declare sum as a float for the purposes of diving it by totalNums to get the mean.
Cast one of the integers to either a float or a double so that the decimals won't get truncated, so the last cout statement would look like this:
cout << "The mean is: " << (double)sum/totalNums << endl;
In C++ the default for precision is 6, but you can change the number of decimal points that are displayed by adding #include <iomanip> and using the setprecision( ) function in the iomanip, which you can just add in the same output line:
cout << setprecision(x) << "The mean is: " << (double)sum/totalNums << endl;
where x is whatever precision you want.
If you want to try using dynamic memory
This is definitely not necessary for what you're doing, but it's interesting stuff and good practice!
One more thing is that if you want to be able to have the user enter integers indefinitely, you can dymanically allocate memory during runtime by declaring a array of pointers to integers (so it's an array of address locations instead of an array of integers) and some sentinal value so they can decide when to stop. That code would look like:
#include <iostream>
#include <iomanip>
using namespace std;
main( ) {
const int ARRAY_SIZE = 200;
const int SENTINAL = -999;
int totalNums = 0;
int sum = 0;
//declare an array of pointers to integers so
//the user can enter a large number of integers
//without using as much memory, because the memory
//allocated is an array of pointers, and the int
//aren't allocated until they are needed
int *arr[ARRAY_SIZE];
cout << "We will be finding a mean." << endl;
cout << "Enter integers (up to 200) or enter -999 to stop" << endl;
//add a conditional into the for loop so that if the
//user enters the sentinal value they will break out
//of the loop
for (int c = 0; c < ARRAY_SIZE; c++) {
//every time you iterate through the loop, create a new
//integer by using the new keyword using totalNums as
//the index
arr[totalNums] = new int;
cout << "Enter integer: ";
//input into the array of pointers by dereferencing it
//(so it refers to what the pointer is pointer to instead
//of the pointer)
cin >> *arr[totalNums];
if (*arr[totalNums] == SENTINAL)
break;
else {
sum += *arr[totalNums];
totalNums++;
}
}
cout << setprecision(3) << "The mean is: " << (float)sum / totalNums << endl;
}

Asking user for const

There is my friend's code. It works, but we would like to ask our user how many times he wants to type informations. Simplier, We don't know how to ask my user for N ("const int N = 3" line). We've tried changing "const int" into "int", but then an error shows up "expression must have a constant value".
#include <iostream>
using namespace std;
struct T_dane_ksiazki
{
char imie[15];
char nazwisko[30];
char tytul[45];
int rokwydania;
int nrwydania;
};
void WCZYTAJ_dane(T_dane_ksiazki& dane) /*wczytanie informacji o książce*/
{
cout << "\nimie autora: ";
cin >> dane.imie;
cout << "nazwisko autora: ";
cin >> dane.nazwisko;
cout << "tytul ksiazki: ";
cin >> dane.tytul;
cout << "rok wydania: ";
cin >> dane.rokwydania;
cout << "numer wydania: ";
cin >> dane.nrwydania;
}
void WYSWIETL_dane(T_dane_ksiazki dane) /*wczytanie informacji o książce*/
{
cout << "\nimie autora: " << dane.imie;
cout << "\nnazwisko autora: " << dane.nazwisko;
cout << "\ntytul ksiazki: " << dane.tytul;
cout << "\nrok wydania: " << dane.rokwydania;
cout << "\nnumer wydania: " << dane.nrwydania << "\n";
}
const int N = 3;
int Zapytajka()
{
cout << N<< "\n";
return 1;
}
int main()
{
T_dane_ksiazki daneq[N];
Zapytajka();
cout << "Podaj informacje o ksiazkach: \n";
for (int i = 0; i<N; i++)
{
WCZYTAJ_dane(daneq[i]);
}
cout << "\n\nInformacje o ksiazkch: \n";
for (int i = 0; i<N; i++)
{
WYSWIETL_dane(daneq[i]);
}
cout << "\nKoniec programu. Nacisnij ENTER";
cin.ignore(); cin.get();
return 1;
}
C++ only supports arrays whose size is constant. However, if you want a non-constant size, you can use vector, which was designed specifically for this purpose.
Example:
#include <vector>
...
int main()
{
Zapytajka();
cout << "Podaj informacje o ksiazkach: \n";
int n;
cin >> n;
std::vector<T_dane_ksiazki> daneq(N); // moved here and modified
for (int i = 0; i<N; i++)
{
WCZYTAJ_dane(daneq[i]);
}
...
}
I changed an array to a vector, and moved its definition to after the value of n is determined. I also changed N to n because it's no longer a constant, and it's a common convention to allocate lower-case names to variables.
Edit: I missed that it is a C++ question. The answer for C++ is that you should use a C++ container, probably a vector. These containers are the reason that the variable length arrays introduced in C in 1999 discussed below do not exist in C++: There is no real need for them. (There is a discussion whether to introduce something like it but it has non-trivial implications for the type system.)
You can have variable length arrays in C99 programs (for gcc: compile with "-std=c99"). That is, you can make N a non-const and the program should still compile and run properly (I didn't check every detail, but it looks pretty straightforward).
In pre-99 C you have to allocate dynamically with malloc or simply define an array which is big enough for the biggest conceivable number and use only part of it.

Trouble with dynamic arrays and finding the sum of values

So as I explained in the title i'm having trouble trying to get the sum of an array. I've just now learned how to create dynamic arrays and I did some searching on how to calculate the sum. I don't believe I fully understand what is going on to calculate the sum.
// Final Grade Calculator
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
int main(){
double minor, quiz, major;
int minorG, quizG, majorG;
minorG = 0;
cout << "Final Grade Calculator" << endl;
cout << "Input minor grade weight percent." << endl;
cin >>minor;
cout << "Input quiz grade weight percent." << endl;
cin >>quiz;
cout << "Input major grade weight percent." << endl;
cin >>major;
// Three grade categories
minor = minor/100;
quiz = quiz/100;
major = major/100;
for(int i = 1; i <=10; i++){
cout << "Input a minor grade. (Max=10)" << endl;
cin >>minorG;
int *minorGA = new int[minorG];
minorG+= minorGA[minorG];
cout << "Currently: " << i << " Grade(s)." <<endl;
}
cout << "Minor Sum: " << minorG << endl;
return 0;
}
This is what I have so far and the trouble I am having is within the for loop which is where my array is and where I am trying to get the sum of it. When I compile and run I get a sum of 138,427. Any help would be greatly appreciated!
I think you're over-complicating things with dynamic arrays. I'll explain what you're doing, and try to provide help for what I think you're trying to do.
In your code int* minorGA = new int[minorG]; you are allocating memory for minorG amount of ints. There are two problems here:
You are accessing an element outside of the memory you allocated. When you allocate 10 elements, you can access elements 0-9. Trying to access 10 is undefined behaviour (you are trying to access parts of memory that could contain anything).
The values stored in this array are just whatever is in memory, so when you are attempting to increment minorG by the amount of one of these, it's just whatever is in memory at the time.
A separate problem is that you are not deallocating the memory, but some might argue that it isn't really a problem.
You should just be able to have the following to perform what I think you're trying to do:
for (int i = 0; i < 10; ++i)
{
int inputtedNumber = 0;
cout << "Enter a number" << endl;
cin >> inputtedNumber;
// add that number to some tally:
finalTally += inputtedNumber;
}
Or if you are trying to store the elements in an array, you can use the following:
const int maxElements = 10;
int grades[maxElements] = {}; // this will construct all elements with 0. Without this, the elements may contain any number.
for (int i = 0; i < maxElements; ++i)
{
int inputtedNumber = 0;
cout << "Enter a number" << endl;
cin >> inputtedNumber;
// Store the number
grades[i] = inputtedNumber;
}
In saying that, it will be better to use std::vector (knows its size, handles memory for you, can grow):
std::vector<int> grades;
// Allow the user to enter as many numbers as they'd like
for (;;)
{
int input = 0;
cout << "Enter a number" endl;
cin >> input;
// Store the number. Will continue to grow
grades.push_back(input);
}