Changing the values of pointers via addresses - c++

This week, we were tasked to create a program where:
Program displays the addresses and values of the array
User inputs the corresponding address he wants to change
User inputs the new value for that address
I was able to figure how a pointer works but it displays another number instead of the inputted value.
Here's the code:
int j =1, var, nx;
int array[4] = {3618, 6555, 5012, 1869};
int* pa; //pointer
char choice;
int remember = 0;
pa = array;
cout << endl;
cout << "\t------------------------" << endl;
cout << "\t\t Values" << endl;
cout << "\t------------------------" << endl;
for(int i = 0; i<4; i++){
cout << "\tarray" << j;
cout << " = " << std::dec << *(pa + i);
cout << " (" << pa + i << ")" << endl;
j++;
}
cout << "\t------------------------" << endl << endl;
cout << "\tPlease enter an address: ";
cin >> hex >>var;
cout << endl;
cout <<"\tYou entered: " << hex << var << endl;
cout << "\tPlease enter a new value: ";
cin >> nx;
pa = (int*)var;
cout << endl;
*pa = nx;
pa = array;
j=1;
cout << endl;
cout << "\t------------------------" << endl;
cout << "\t\t New Values" << endl;
cout << "\t------------------------" << endl;
for(int i = 0; i<4; i++){
cout << "\tarray" << j;
cout << " = " << std::dec << *(pa+i);
cout << " (" << &array[i] << ")" << endl;
j++;
}
cout << "\t------------------------" << endl << endl;

The problem is cin >> nx; is reading the value as hex. I'm quite sure this is happening because the previous use of cin in the program read the value as hex: cin >> hex >>var;. I observed the same thing happening with a cout statement I added to your program when testing it.
If that is changed to cin >> std::dec >> nx;, the behavior of the program is correct.
E.g., using your test run: 353 in hex when converted to decimal is 851.
A helpful tip for future: You don't need the j variable: inside the for loops you can just use i + 1.

What OP is seeing is the the hex modifier still being in effect.
cin >> hex >>var;
turns on hex. Nothing turned it off again.
So when OP types in 353, the program interprets it as a hexadecimal number. 0x353 == 851.
Solution:
Revert to decimal input.
cin >> dec >> nx;

A good habit to get into is to use descriptive words as your variables. It makes it a whole lot easier to debug, and more importantly understand what is going on.
Now, if I'm interpreting this correctly, you are setting pa equal to a new pointer called var, instead of setting pa equal to var. Here is a reference page on pointers, Scroll to the dereference operator to see what I was talking about. The (int*) is unnecessary.

Related

Selecting an array value using a random number generator

its a text based monopoly game where i need the dice to select the number from the array like on a board.
I have the number generator, what i need to do though is when the value comes up it pluses it on the array to get the matching number so for example if the players rolls a 6, the 6 + array 0 = array value 6 which will be a name of a street but it means the player knows which place on the made up board they are on. here is the coding i am using to try and do so but i keep on getting 006ff65 what ever. i how can i get it for showing just the number as the names will be added later.
{
int main()
{
int number = 12;
int rnum = (rand() % number) + 1;
int house = 1;
int moneyscore = 10000;
double values[] = {
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40 };
char name[50];
cout << "Who are you, Dog, Car, Hat or Bus" << endl;
cin.getline(name, 50);
cout << "Welcome to Our Game " << name << " You have " << moneyscore << " .PLease Roll dice to get started" << endl;
cout << "\n----------------------Press any Enter to roll dice----------------------" << endl;
system("cls");
int choiceOne_Path;
cout << "# You roll a " << rnum << endl;
rnum = values[rnum];
cout << "# you have " << moneyscore << endl;
cout << "# You move to grid "<< values << endl;
cout << "\t >> Enter '1' Buy Property" << endl;
cout << "\t >> Enter '2' Recieve Rent" << endl;
cout << "\t >> Enter '3' End turn" << endl;
retry:
cout << "\nEnter your choice: ";
cin >> choiceOne_Path;
if (choiceOne_Path == 1)
{
cout << "\n Buy Property " << endl;
cout << " " << name << " has " << moneyscore << endl;
cout << " " << house <<" House has been placed by " << name <<" who spent 2,500" << endl;
moneyscore -= 2500;
cout << " " << name << " now has " << moneyscore << endl;
cout << "\n Roll again" << endl;
cout << "# You roll a " << rnum << endl;
}
else if (choiceOne_Path == 2)
{
cout << "\n You recieved 2500 from rent" << endl;
moneyscore += 2500;
cout << " " << name << "\n now has" << moneyscore << endl;
cout << "\n(Player will gain money form house, will need to find a way in order to make the
console remember what score == to postion)" << endl;
cout << "Ends turn" << endl;
}
else if (choiceOne_Path == 3)
{
cout << "\n Roll again" << endl;
cout << "# You roll a " << rnum << endl;
}
else
{
cout << "You are doing it wrong, player! Press either '1' or '2', nothing else!" << endl;
goto retry;
}
cout << "\n----------------------Press any key to continue----------------------" << endl;
_getch();
}
}
As far as I know, you should use srand (time(NULL)); between every call to rand() to correctly return a new random number from every call.
"srand" initialize the random number generator using a seed. In this case seed is time, which should be different on every call.
Pretty basic. You either made a few typos or need to learn how arrays work (and program flow, and subroutines, but perhaps that is for later lessons.)
First you are assigning the result of the array lookup back into your random number: rnum = values[rnum]; which is not a big deal except you use that variable later and it no longer contains what you may think it does. It actually contains the value you are looking for!
Second the variable values is a pointer to the head of your array so you are outputting the address of the values array with this line: cout << "# You move to grid "<< values << endl; there is no array look up happening at all here. It is strange you missed that because you did reference the array contents properly when you replaced the random number value earlier.

How do I change a char's values?

I've created a program and it runs, however there are two problems. 1) Char doesn't change values as it should. 2) One of my total variables is stuck on one.
I've tested the code multiple times, and the char deptID is stuck on 'B'. I've tried going through the workflow and it's stuck on the value. Just to make sure, I wrote a cout line to check it throughout the workflow. Regardless of what I input, it's stuck on 'B'.
2) The variable TechTotal is seemingly stuck on 1. I've tested it using different values as well. I also went ahead and used a cout line to determine the value throughout the workflow to no success. I've made sure the variables are correct in calculating the variable. Both are correct.
Here's my main code:
int main(int argc, char** argv) {
welcomeScreen();
long int empID;
int TechAccAvg, TechTixAvg;
int BusTotal, TechTotal, BusAccAvg, BusTixAvg;
char deptID;
for (int i=0; i < 2; i++)
{
cout << "What department are you apart of?\n";
cin >> deptID;
if (deptID = 'B')
{
auto Averages = gatherData(deptID);
BusTixAvg = std::get<0>(Averages);
BusAccAvg = std::get<1>(Averages);
cout << BusTixAvg << endl;
cout << BusAccAvg << endl;
BusTotal = BusTixAvg + BusAccAvg;
cout << "Bus Total: " << BusTotal << endl;
}
else if (deptID = 'T')
{
auto TechAverages = gatherData(deptID);
TechTixAvg = std::get<0>(TechAverages);
TechAccAvg = std::get<1>(TechAverages);
cout << TechTixAvg << endl;
cout << TechAccAvg << endl;
TechTotal = TechTixAvg + TechAccAvg;
cout << "Tech Total: " << TechTotal << endl;
}
}
cout << "Tech: " << TechTotal << endl;
cout << "Business: " << BusTotal << endl;
summaryReport(TechTotal, BusTotal);
goodByeScreen();
return 0;
}```
` std::tuple<int, int> gatherData (char dept)
{
tuple <double, double> Averages;
int employeeNum=0, TotalTix=0, TotalAcc=0, trafficTickets=0, accidents=0;
long int empID=0;
double TixAverage=0, AccAverage=0;
char deptID;
cout << dept << endl;
cout << "How many employees do you have?\n";
cin >> employeeNum;
for(int j = 0; j < employeeNum; j++)
{
cout << "Please enter your employees ID number\n";
cin >> empID;
cout << "How many tickets did they have this year?\n";
cin >> trafficTickets;
TotalTix += trafficTickets;
cout << "How many accidents did they have this year?\n";
cin >> accidents;
TotalAcc += accidents;
}
TixAverage = TotalTix / employeeNum;
AccAverage = TotalAcc / employeeNum;
cout << "Department: " << dept << endl;
cout << "Total employees: " << employeeNum << endl;
cout << "Total tickets: " << TotalTix << endl;
cout << "Total Accidents: " << TotalAcc << endl;
Averages = make_tuple (TotalTix, TotalAcc);
return Averages;
}```
This is used to create the tuple that is used in determining Totals for both 'B' and 'T' depts.
Fixing both the char dept and the TechTotal would fix the entire program, I think. Those are the only things holding the program back. I've been stuck on this problem for a few hours now and I'm kind of lost as to why it's not changing those values. Any help would be appreciated, thank you in advance!
Solution
Replace else if (deptID = 'T') with else if (deptID == 'T') and if (deptID = 'B') with if (deptID == 'B').
Explanation
The single equal sign = means assignment. Therefore, everytime the program runs, deptID will be assigned to B and the statement will return true, satisfying the if statement.
However, you want to compare two values to see if they are equal. Therefore, you must use == (equality).
Because the statements in the else if will never execute, TechTotal will remain uninitialised, and the value in that memory address just so happens to be 1.

Creating and clearing an array of structures

I've been trying to write a short program allowing the user to add entries to a "database", listing the entries they have put in, and the ability to clear all the entries without ending the program. Here's what i've got
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
struct BIRTH
{int month; int year;};
struct ID
{string name; bool vip; float score;
struct BIRTH date;} ;
int main(int argc, char** argv) {
ID **ptrarr;
ptrarr = new ID * [10];
for (int r=0; r<10; r++)
{ptrarr[r] = new ID[1] ;}
int counter = 0;
while(counter<100){
cout << "Type add to create a new entry" << endl;
cout << "Type list to see all entries" << endl;
cout << "Type clear to delete all entries" << endl;
cout << "Type exit to terminate" << endl;
string command = "0";
getline (cin,command);
if(command=="add")
{
cout << "Enter name" << endl;
getline (cin,ptrarr[counter][1].name);
cout << "VIP? 1 for yes, 0 for no" << endl;
cin >> ptrarr[counter][1].vip;
cout << "Enter score" << endl;
cin >> ptrarr[counter][1].score;
cout << "Month of birth" << endl;
cin >> ptrarr[counter][1].date.month;
cout << "Year of birth" << endl;
cin >> ptrarr[counter][1].date.year;
counter++;
}
else if(command=="list")
{
for (int i=0; i<counter; i++)
{int n=i+1;
cout << n << " "
<< ptrarr[i][1].name << " ";
if (ptrarr[i][1].vip)
{cout << "VIP ";}
cout << "Score: " << ptrarr[i][1].score << " "
<< "Born: " << ptrarr[i][1].date.month << "/" << ptrarr[i][1].date.year << endl;
}
}
else if(command=="clear")
{delete[] ptrarr;
cout << "Entries cleared" << endl;}
else if(command=="exit")
{return 0;}
else
cout << "try again" << endl;
}
return 0;
}
Now here's the deal: the following code successfully compiles, but when I type in the "add" command, the program crashes (achievement unlocked, didn't think it's possible to obtain with such a short code). The most important thing is that the array is made of a multitype structure and that the "clear" command wipes out all the entries in the array.
NOTE: I understand that there are thousand better ways to write this piece of code, but I'm writing it to practice the things I have covered so far regarding C++. So unless it is absolutely necessary for the code to run, please do not introduce any new gimmicks =)
Replace all ptrarr[counter][1] with ptrarr[counter][0] fixes the problem.
Further advices:
I. This code has redundancy:
ID **ptrarr;
ptrarr = new ID * [10];
for (int r=0; r<10; r++)
{ptrarr[r] = new ID[1] ;}
Replace it with:
ID *ptrarr;
ptrarr = new ID [10];
Then you do not need extra [0] at the end of each ptrarr[counter]
II. functions make your code more readable:
if(command=="add")
add();
else if(command=="list")
list();
else if(command=="clear")
clear();
else if(command=="exit")
return 0;
else
cout << "try again" << endl;
Then decisions are made in a smaller area (Good practice for large programs.)
III. There is another mistake in your code:
else if(command=="clear")
{delete[] ptrarr;
cout << "Entries cleared" << endl;}
Here you should reset the counter. Also if you regard my point (I) this part is fine. Otherwise, if you use new with a for loop, I am afraid that you need to delete with a for loop too. Merely removing the root of the array tree brings you memory leak!
Also, if you cleared the list by delete, wont you need to store data in the list anymore? Using delete in linked lists is a good idea, but it does not apply here. Just reseting the counter does the job and it does not show IDs in the list anymore. The for inside the list does only count up to the counter.
If you exit the program don't you free the memory?
I say
delete [] ptrarr;
is good for being at exit.
You are creating an an array of pointers, each one of which points to one element:
ptrarr[r] = new ID[1] ;
The maximum index that you can use with ptrarr[r] is 0. Since you are using ptrarr[counter][1], you are accessing memory that is out of bounds. This leads to undefined behavior. Crashing is one such undefined behavior.
There are other issues with your code that you may want to fix.
More out of bounds memory access
You are using:
int counter = 0;
while(counter<100){
...
getline (cin,ptrarr[counter][1].name);
That is again going to lead to undefined behavior if counter > 10 since you allocated only 10 pointers for ptrarr.
Deleting the contents
You are using:
else if(command=="clear")
{
delete[] ptrarr;
cout << "Entries cleared" << endl;
}
There are couple of problems with this:
You have memory leak. You never call delete [] on what ptrarr[0] - ptrarr[9] point to. You'll have to use:
else if(command=="clear")
{
for ( int i = 0; i < 10; ++i )
{
delete [] ptrarr[i];
}
delete[] ptrarr;
cout << "Entries cleared" << endl;
}
Remember that every allocation must have a corresponding deallocation. Otherwise, you are leaking memory.
Once you call delete [] ptrarr;, it points to dangling memory. I don't see any code that reallocates memory for ptrarr while you continue to use it.
You need to reallocate memory and reset counter to 0 when the user chooses "clear".
My suggestion
You don't two levels of pointers. You just need something like:
int const MAX_ITEMS = 100;
ID* IDarr = new ID[MAX_ITEMS];
Instead of ptrarr[counter][1], use IDarr[counter].
Use MAX_ITEMS in the expression of the while statement instead of the magic number 100.
int counter = 0;
while(counter<MAX_ITEMS){
When processing "clear", you don't need to deallocate or allocate memory. Just reset counter.
else if(command=="clear")
{
counter = 0;
cout << "Entries cleared" << endl;
}
Make sure to deallocate memory before returning from main.
Here's the complete main function with the changes:
int main(int argc, char** argv) {
const int MAX_ITEMS = 100;
ID* IDarr = new ID[MAX_ITEMS];
int counter = 0;
while(counter < MAX_ITEMS){
cout << "Type add to create a new entry" << endl;
cout << "Type list to see all entries" << endl;
cout << "Type clear to delete all entries" << endl;
cout << "Type exit to terminate" << endl;
string command = "0";
getline (cin,command);
if(command=="add")
{
cout << "Enter name" << endl;
getline (cin, IDarr[counter].name);
cout << "VIP? 1 for yes, 0 for no" << endl;
cin >> IDarr[counter].vip;
cout << "Enter score" << endl;
cin >> IDarr[counter].score;
cout << "Month of birth" << endl;
cin >> IDarr[counter].date.month;
cout << "Year of birth" << endl;
cin >> IDarr[counter].date.year;
counter++;
}
else if(command=="list")
{
for (int i=0; i<counter; i++)
{
int n=i+1;
cout << n << " " << IDarr[i].name << " ";
if (IDarr[i].vip)
{
cout << "VIP ";
}
cout
<< "Score: " << IDarr[i].score << " "
<< "Born: " << IDarr[i].date.month << "/" << IDarr[i].date.year << endl;
}
}
else if(command=="clear")
{
counter = 0;
cout << "Entries cleared" << endl;
}
else if(command=="exit")
{
// Don't use return 0;
// Just break out of the while loop so that memory
// can be deallocated at the end of this function.
break;
}
else
cout << "try again" << endl;
}
delete [] IDarr;
return 0;
}
Array indices start at 0.
ptrarr[counter][1] refers to the second element of ptrarr[counter]. ptrarr[counter] points to an array of one element.
try this :
if(command=="add") {
cout << "Enter name" << endl;
getline (cin,ptrarr[counter][0].name);
cout << "VIP? 1 for yes, 0 for no" << endl;
cin >> ptrarr[counter][0].vip;
cout << "Enter score" << endl;
cin >> ptrarr[counter][0].score;
cout << "Month of birth" << endl;
cin >> ptrarr[counter][0].date.month;
cout << "Year of birth" << endl;
cin >> ptrarr[counter][0].date.year;
counter++;
}
else if(command=="list") {
for (int i=0; i<counter; i++){
int n=i+1;
cout << n << " "<< ptrarr[i][0].name << " ";
if (ptrarr[i][0].vip){
cout << "VIP ";
}
cout << "Score: " << ptrarr[i][0].score << " "
<< "Born: " << ptrarr[i][0].date.month << "/" << ptrarr[i][0].date.year << endl;
}
}
Conclusion :
Just as you initialized counter with 0 you should have used 0 index to access the first element;
Same goes while listing.
Arrays are 0 index based.

Float Variable Not Working Inside Switch Statment

So this program is supposed to collect weather temperatures over 7 days using a for loop and then basically just print them back out to the user with an average temperature and the highest recorded temperature. Keep in mind, the following piece of code is a part of a much larger program. Anyway, the problem seems to be the "highest_temp1" float variable. When I run the program it produces some sort of error code instead of the highest temperature. This piece of code was tested in a separate source file and it works no problem.
switch (choice)
{
case 3:
int n;
float temperatures [7];
float lastweektemp [7] = {12.56,8.65,7.5,10,7.9,5,8};
float highest_temp1, highest_temp2;
float accumulated_temp1, accumulated_temp2;
system("CLS");
cout << "____________Weather Data____________" << endl << endl;
for (n = 0; n<7; n++)
{
cout << "What is the temperature for Day " << n+1 << " ?" << endl;
cin >> temperatures[n];
if (highest_temp1 < temperatures [n])
{
highest_temp1 = temperatures [n];
}
if (highest_temp2 < lastweektemp [n])
{
highest_temp2 = lastweektemp [n];
}
accumulated_temp1 = accumulated_temp1 + temperatures[n];
accumulated_temp2 = accumulated_temp2 + lastweektemp [n];
}
cout << endl << " Day This Week Last Week" << endl;
for (n=0; n<7; n++)
{
cout << n+1 << temperatures[n] << lastweektemp[n] << endl;
}
system("CLS");
cout << " Weather Report" << endl;
cout << " --------------" << endl << endl;
cout << "Current Week: " << endl;
cout << "-------------" << endl;
for (n=0; n<7; n++)
{
cout << "Day " << n+1 << ": " << temperatures[n] << endl;
}
cout << endl << " Average: " << accumulated_temp1 / 7 << endl;
cout << " Highest Temperature: " << highest_temp1 << endl;
cout << "Last Week: " << endl;
cout << "----------" << endl;
for (n=0; n<7; n++)
{
cout << "Day " << n+1 << ": " << lastweektemp[n] << endl;
}
cout << endl << " Average: " << accumulated_temp2 / 7 << endl;
cout << " Highest Temperature: " << highest_temp2 << endl;
system("PAUSE");
}
The highest temperature in current week is 24 but it is printing "Highest Temperature: 3.45857e+032"
This exact 'error-code' is appearing every time I run the program it doesn't change.
I am a newbie hence why I can't upload a photo.
Any help would be appreciated. I'm doing a small assignment in college. This is my first question so go easy !!
You have not assigned any value to teh variable highest_temp1 and you are comparing it with another value.
Basically you will need to assign it a value first before you compare..
highest_temp1 = 10.00
(or anything that it is supposed to contain)
You have not initialised highest_temp1 (or highest_temp1 for that matter: after that I stopped looking).
Same for accumulated_temp, which gets not initialised. can be done via
float accumulated_temp1(0);
Initialize variables before using them
float highest_temp1(-FLT_MAX); // -FLT_MAX insures results of first compare
float highest_temp2(-FLT_MAX); // Could use -1.0/0.0 of -INFINITY instead
float accumulated_temp1(0.0);
float accumulated_temp2(0.0);
For float number condition use if statements switch is not able to work in case of float number, switch only work for integer number.

Check for non-numeric inputs in a C++ program

How do you check for non-numeric input using C++? I am using cin to read in a float value, and I want to check if non-numerical input is entered via stdin. I have tried to use scanf using the %d designator, but my output was corrupted. When using cin, I get the correct format, but when I enter, a string such as "dsffsw", I get an infinite loop.
The commented code was my attempt to capture the float, and type cast it as string, and check if it is a valid float, but the check always comes up false.
I have tried using other methods I have found on the message boards, but they want to use scanf in C and not cin in C++. How do you do this in C++? Or in C if it is not feasible.
while (!flag) {
cout << "Enter amount:" << endl;
cin >> amount;
cout << "BEGIN The amount you entered is: " << strtod(&end,&pend) << endl;
//if (!strtod(((const char *)&amount), NULL)) {
// cout << "This is not a float!" << endl;
// cout << "i = " << strtod(((const char *)&amount), NULL) << endl;
// //amount = 0.0;
//}
change = (int) ceil(amount * 100);
cout << "change = " << change << endl;
cout << "100s= " << change/100 << endl;
change %= 100;
cout << "25s= " << change/25 << endl;
change %= 25;
cout << "10s= " << change/10 << endl;
change %= 10;
cout << "5s= " << change/5 << endl;
change %= 5;
cout << "1s= " << change << endl;
cout << "END The amount you entered is: " << amount << endl;
}
return 0;
}
int amount;
cout << "Enter amount:" << endl;
while(!(cin >> amount)) {
string garbage;
cin.clear();
getline(cin,garbage);
cout << "Invalid amount. "
<< "Enter Numeric value for amount:" << endl;
}
I think you task relates to the so called defensive programming, one of it`s ideas is to prevent situations like one you described (function expects one type and user enters another).
I offer you to judge whether input is correct using method that returns stream state , which is good(),
so I think it will look something like this:
int amount = 0;
while (cin.good()) {
cout << "Enter amount:" << endl;
cin >> amount;