I am working to create a function where I take in 6 values (3 strings, 3 ints), store those values in arrays, then print out each of those values in pairs of 2
Here is what I have:
#include <iostream>
#include <string>
using namespace std;
int main()
{
const int SIZE = 3;
int time[SIZE] = {};
string name[SIZE] = {};
for (int a = 0; a < 3; a++)
{
cout << "Enter runner name: ";
getline (cin, name[+1]);
cout << "Enter runner time: ";
cin >> time[+1];
cin.ignore();
}
for (int a = 0; a < 3; a++)
{
cout << name << " finished in " << time << "\n";
}
return 0;
}
I would like my output to look like this:
name1 finished in time1
name2 finished in time2
name3 finished in time3
Currently, my output looks like this:
0x22fdf0 finished in 0x22fe10
0x22fdf0 finished in 0x22fe10
0x22fdf0 finished in 0x22fe10
How can I get the inputs to be stored in the arrays then output those values to the user?
If this has been answered already, apologies. I haven't been able to find an example where the arrays are populated with user input values and then returned to the display.
You need to actually index the array using the [] subscript operator. Likewise, when printing, you should attempt to index an element in the array. Since when you attempt to print the array itself, the compiler will implicitly convert the array to a pointer, which, when printed, will print the memory address of the first element in that array, rather than the element itself.
So you could dereference the arrays to get the first value in each, but a better way is to index it by the a variable in your for loop, like so:
#include <iostream>
#include <string>
using namespace std;
int main() {
const int SIZE = 3;
int time[SIZE] = {};
string name[SIZE] = {};
for (int a = 0; a < 3; a++) {
cout << "Enter runner name: ";
getline(cin, name[a]);
cout << "Enter runner time: ";
cin >> time[a];
cin.ignore();
}
for (int a = 0; a < 3; a++) {
cout << name[a] << " finished in " << time[a] << "\n";
}
return 0;
}
Alternatively, if you wanted to not index it, you could use your original approach, but then you would have to dereference the pointer using the * dereference operator:
for (int a = 0; a < 3; a++) {
cout << *name << " finished in " << *time<< "\n";
}
However, now you would simply print the first element three times. So to remedy this, you need to employ some pointer arithmetic, and increase the value by a, to get the elements, 0, 1, and 2 past the first element respectively:
for (int a = 0; a < 3; a++) {
cout << *(name + a) << " finished in " << *(time + a)<< "\n";
}
So some things to look up:
* Dereferncing
* Subscripting
* Implicit array to pointer conversion
Related
I've been working on the Euler 29 problem for a few days and am having difficulty getting the mpz_t type to work correctly. The objective is to iterate through a^b for values of 2 <= a,b <= 100 and count the nonrepeat values.
Using vector I was able to store the values using pointers in an array like so:
mpz_t a;
mpz_init(a);
vector<mpz_t*> numbers;
numbers.push_back(&a);
However, when running the full program below you can see that after it inserts the first value 4, it doesn't insert any new values. This is because the temp value being compared to rop is not being set to what is already in the array, and instead is set to the value shared by rop.
#include <iostream>
#include <vector>
#include <chrono>
#include "gmp.h"
using namespace std;
int main()
{
auto start = std::chrono::high_resolution_clock::now();
int solution = 0;
bool found = false;
int r = 10;
mpz_t rop;
mpz_init(rop);
mpz_t temp;
mpz_init(temp);
vector<mpz_t*> numbers;
for(int a = 2; a <= 5; a++)
{
for(int b = 2; b <= 5; b++)
{
mpz_ui_pow_ui(rop, a, b);
for(int i = 0; i < numbers.size(); i++)
{
cout << "i: " << i << endl;
cout << "rop: ";
mpz_out_str(stdout,10,rop);
cout << endl;
mpz_set(temp,*(numbers.at(i)));
cout << " temp: ";
mpz_out_str(stdout,10,temp);
cout << endl;
r = mpz_cmp(rop,temp);
cout << " r: " << r << endl << endl;
if(r == 0)
{
found = true;
break;
}
}
if(found == false)
{
numbers.push_back(&rop);
solution++;
cout << "pushed! " << endl << endl;
}
found = false;
}
}
auto done = std::chrono::high_resolution_clock::now();
cout << "Solution: " << solution << endl << endl;
cout << "Program completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(done - start).count() << " milliseconds." << endl;
}
This line of code should be setting temp equal to 4 at the start of the forloop, but instead sets it equal to rop:
mpz_set(temp,*(numbers.at(i)));
Since the problem clearly has to do with the fact I'm using pointers and passing the actual address in memory to store these mpz_t variables, how can I change the code so that it is able to work properly? I'm under the impression using the function mpz_clear(rop) after each push_back to the numbers vector wouldn't work as it releases the address from memory.
I figured out that due to the way mpz_t variables work the mpz_set function does not work with a pointer to mpz_t type variables as a parameter.
Instead, I was able to get the program to work by assigning the mpz_get_str function to a string and pushing that to a vector of strings to check for repeat values.
mpz_t rop;
mpz_init(rop);
char * num;
vector<string> numbers;
num = mpz_get_str(num,10,rop)
numbers.push_back(num);
Is there a way to condense five for-loops into one and have them display different variables and letters for each? Currently, I have one loop with five other loops and if/else to keep it condense, but this seems redundant and defeats the very purpose of making the loop.
So I decided to post the whole source code so people can understand what I am trying to get at more. This is a program that creates 100 random grades everytime it runs and I have to sort them, then display them. I am aware I could do 5 for loops, but I want to write code that is more condensed and efficient.
The hard part is writing a loop that can display 5 arrays consistently even though the size of the array changes every run.
#include <iostream>
#include <vector>
using namespace std;
int main(){
int grades[100];
int sizeA=0, sizeB=0, sizeC=0, sizeD=0, sizeF=0;
std::vector<int> gradeA, gradeB, gradeC, gradeD, gradeF;
srand(time(NULL));
for(int i = 0; i < 100; i++){
grades[i] = rand() % 100 + 1;
}
for(int i = 0; i < 100; i++){
if (grades[i] < 100 || grades[i] > 0){
if (grades[i]>=90)
gradeA.push_back(grades[i]);
else if (grades[i]>=70)
gradeB.push_back(grades[i]);
else if (grades[i]>=50)
gradeC.push_back(grades[i]);
else if (grades[i]>=20)
gradeD.push_back(grades[i]);
else if (grades[i])
gradeF.push_back(grades[i]);
} else {
cout << "uhh.. ";
return(0);
}
}
sizeA = gradeA.size();
sizeB = gradeB.size();
sizeC = gradeC.size();
sizeD = gradeD.size();
sizeF = gradeF.size();
/**toggle ? showgrades(gradeA, size) : (int?)null;**/
}
How about using a function to do the looping and call it with the required information
void printGrades(const std::vector<int>& grades, char level) {
cout << num << " " << level << " students: ";
for(int i = 0; i < grades.size(); i++){
cout << grades[i] << " ";
cout << endl;
}
So when you want to print them all:
printGrades(gradeA, 'A');
printGrades(gradeB, 'B');
printGrades(gradeC, 'C');
printGrades(gradeD, 'D');
printGrades(gradeF, 'F');
If I were you, I would create a class Student, and then a 2D array, where every row would represent the student's category, and the number of columns of a row, the number of students.
That could be represented as a fixed-sized array of size 5, where every cell would be a std::vector of class Student.
Minimal working example:
#include <iostream>
#include <vector>
using namespace std;
class Student {
public:
Student(int grade, char category) : grade(grade), category(category) {}
int getGrade(void) { return grade; }
char getCategory(void) { return category; }
private:
int grade; // 0, ..., 20
char category; // A, ..., F
};
int main(void) {
vector<class Student> std[5]; // cell 0 is for A students, ..., cel 4 is for F students
std[0].push_back({20, 'A'}); std[0].push_back({19, 'A'});
std[1].push_back({15, 'B'});
std[2].push_back({17, 'C'}); std[2].push_back({17, 'C'});
std[3].push_back({14, 'D'});
std[4].push_back({15, 'F'});
for (int i = 0; i < 5; ++i) {
if(std[i].size()) {
cout << std[i].size() << " " << std[i][0].getCategory() << " students: ";
for (auto& student : std[i]) {
cout << student.getGrade() << " ";
}
cout << endl;
}
}
return 0;
}
Output:
2 A students: 20 19
1 B students: 15
2 C students: 17 17
1 D students: 14
1 F students: 15
Appendix:
I understand that you want to make the code compact, but this:
for(int a = 0; a < sizeA; a++){
cout << gradeA[a] << " ";
} aS = 1; bS = 0; cout << endl;
is not cool, since it's not readable for the reader. I suggest you to change it to:
for(int a = 0; a < sizeA; a++){
cout << gradeA[a] << " ";
}
aS = 1;
bS = 0;
cout << endl;
since a reader expects to see no code after the closing curly bracket. That's a general statement.
*Edit: Still, when input 3 columns for the 1st row and 2 columns for the 2th, in the output 1st row becomes 2-elemented as the first.
Problem with outputting dynamically allocated number of equipes with separately dynamically allocated number of columns (for number of catches for the each equip)... Namely, if I try to allocate 2 equipes and then for the first equip two "catches" of fish (two columns) and for second equip three catches of fish, everything is o.k.... but if I try input of smaller number of columns ("catches") for the second row (equip) then in the output the "excess" of the first row is "cutted off", so for example if there where a 3 columns input for the 1st row and 2 columns input for the second row, in the output there will be just two columns (indices of numbers) for the every of the two rows.
#include<iostream>
int main()
{
using namespace std;
int *sum;
int *a = new int;
int *b = new int;
cout << "Total number of equips: ";
cin >> *a;
// Allocate a two-dimensional 3x2 array of ints
int** ippArray = new int*[*a];
for (int i = 0; i < *a+1; ++i) {
ippArray[i] = new int[*b];
}
// fill the array
for (int i = 1; i < *a+1; ++i) {
cout << "Total number of catches for " << i << "th equip : ";
cin >> *b;
cout << "Equip number: " << i << endl;
for (int j = 1; j < *b+1; ++j) {
cout << "Catch number: " << j << endl;
cin >> ippArray[i][j];
ippArray[i][j];
}
}
// Output the array
for (int i = 1; i < *a+1; ++i) {
for (int j = 1; j < *b+1; ++j) {
cout << ippArray[i][j] << " ";
*sum = *sum + ippArray[i][j];
}
cout << endl;
}
cout << endl;
cout << "All catches of the all equipes: " << *sum-3;
// Deallocate
for (int i = 1; i < *a+1; ++i) {
delete [] ippArray[i];
}
delete [] ippArray;
// Keep the window open
cin.get();
return 0;
}
First, don't make your integers into pointers (int *a = new int;) unless they really need to be. It makes the code much harder to read, and if anyone has to maintain your code they'll call you an a-hole.
Second, int** ippArray = new int*[*a]; combined with multiple spots where you do this... for (int i = 1; i < *a+1; ++i) are bad. ippArray has valid references from 0 to *a, therefore it should be for (int i = 0; i < *a; ++i)
Edit: Try something like this http://ideone.com/4egQl3
Edit2: Also the standard advice...
{
std::vector<string> advice;
advice.push_back( "These will make your life easier" );
}
// No de-allocation needed!
Parts of your program that have undefined behaviour
Use of *b before you assign to it
Access out-of-bounds elements of all your arrays
Never initialise sum
Use of *sum before you assign to it
cleaned up, your code becomes
int main()
{
using namespace std;
int sum, a, b;
cout << "Total number of equips: ";
cin >> a;
typedef vector<vector<int> > vvint;
typedef vector<int> vint;
// Allocate a two-dimensional structure of ints
vvint ippArray(a);
// fill the array
for (vvint::size_t i = 0; i < a; ++i) {
cout << "Total number of catches for " << i+1 << "th equip : ";
cin >> b;
cout << "Equip number: " << i+1 << endl;
ippArray[i] = vint(b);
for (int j = 0; j < b; ++j) {
cout << "Catch number: " << j+1 << endl;
cin >> ippArray[i][j];
}
}
// Output the array
for (const vint & inner : ippArray) {
for (int num : inner) {
cout << num << " ";
sum += num;
}
cout << endl;
}
cout << endl;
cout << "All catches of the all equipes: " << sum;
cin.get();
return 0;
}
So I have written a function that should simply add the values of each element stored in two separate arrays, and save them to a third array.
I don't understand what the issue is, I am simply adding together the value of the int stored at the location referenced by each of my pointers, and saving it to my third, empty, array.
My code compiles just fine, but when I loop to print the contents of my third array (which should contain the sum of the two previous arrays elements at their respective indexes) it just prints a bunch of memory addresses. What gives?
EDIT: I fixed my while loop to perform the arithmetic, and everything is working well. My working code is below. Hope it helps someone else.
#include<iostream>
#include<stdlib.h>
using namespace std;
void arrayAdd(int firstArray[], int secondArray[], int targetArray[], int size){
int *firstPtr = firstArray;
int *secondPtr = secondArray;
int *tragetPtr = targetArray;
while (firstPtr <= &firstArray[size - 1] ){
//add the first two array elements
*tragetPtr = (*firstPtr + *secondPtr);
// point to the next location
*firstPtr++;
*secondPtr++;
*tragetPtr++;
}
}
int main() {
int totalElements;
const size_t ARRAY_SIZE = 50;
int firstIntegerArray[ARRAY_SIZE];
int secondIntegerArray[ARRAY_SIZE];
int thirdIntegerArray[ARRAY_SIZE];
cout << "Please enter the total number of elements for your array: ";
cin >> totalElements;
for(int i = 0; i < totalElements; i++){
cout << "Please enter a value for the first array at index " << i << ": ";
cin >> firstIntegerArray[i];
}
for(int i = 0; i < totalElements; i++){
cout << "Please enter a value for the second array at index " << i << ": ";
cin >> secondIntegerArray[i];
}
//run our arrayAdd function
arrayAdd(firstIntegerArray, secondIntegerArray, thirdIntegerArray, totalElements);
cout << "The conents of your two arrays added together is; " << endl;
for(int i = 0; i < totalElements; i++){
cout << thirdIntegerArray[i] << ", ";
}
return 0;
}
A local array decays to a pointer when it is passed to a function, so you can't use sizeof on it anymore. Indeed this:
void arrayAdd(int firstArray[]) {
int *firstPtr = firstArray;
std::cout << "sizeof(firstArray) == " << sizeof(firstArray) << std::endl;
std::cout << "sizeof(firstPtr) == " << sizeof(firstPtr) << std::endl;
}
int main() {
int test[] = {1,2,3,4,5,6,7,8,9,0};
arrayAdd(test);
return 0;
}
Prints:
sizeof(firstArray) == 8
sizeof(firstPtr) == 8
on my 64 bit machine.
Casting int[] to int* doesn't change anything since it already became a pointer as an argument. You should pass the size of the array to the method or, since you are working with C++, use an std::array or std::vector which will just solve any problem.
Can you help me with a problem on populating an array of 5 circles with random numbers.
The random number would be the radius of the circles.
Here is my code:
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
// Array 2, below section is to populate the array with random radius
float CircleArrayTwo [5]; // store the numbers
const int NUM = 5; // Display 5 random numbers
srand(time(NULL)); // seed the generator
for(int i = 0; i < NUM; ++i)
{
CircleArrayTwo[i] = rand()%10;
}
cout << "Below is the radius each of the five circles in the second array. " << endl;
cout << CircleArrayTwo << endl;
system("PAUSE");
return 0;
}
Currently is output the following:
Below is the radius each of the five circles in the second array.
002CF878
Where am I going wrong?
Any help is much appreciated
You are printing the address of the first element of the array.
You could loop over the array and print each element:
for(int i = 0; i < NUM; ++i)
{
std::cout << CircleArrayTwo[i] << ", ";
}
std::cout << "\n";
Or, if you have C++11 support,
for (auto& x : CircleArrayTwo) {
std::cout << x << ", ";
}
std::cout << "\n";
The way you populated the array is correct, however you cannot print an array like that. You need to write a loop to output the values one by one.
In C(and C++) arrays are almost equivalent to pointers to the beginning of memory location. So you're just outputting the adress of the first element;
To output all elements introduce another loop:
for(int i = 0; i < NUM; ++i)
{
cout << CircleArrayTwo[i] << endl;
}
CircleArrayTwo is a pointer. When you print a pointer, it prints a memory address, like the one you provided. In order to print the values of an array, you need to use the [] notation that you have for the insert.
You could loop over the values in the array and print each one:
for (int i = 0; i < NUM; ++i) { cout << CircleArrayTwo[i] << endl; }