So currently I am still confused in using pointers and reference and I do not know if what I am doing is right. My program is a calculator that stores everything the user inputs. There is an option that the user will be asked if he/she want to view the history and if he/she wants it the program will show all the data he/she inputs.And I need to use pointers and reference in my program but I am still confused on how to use pointers and reference into array
Here is my initialization:
int main() {
int size = 1, fNum[size], sNum[size];
char oprtn[size], answer;
;
float result[size];
int *ptrf = &fNum[size];
int *ptrs = &sNum[size];
char *ptro = &oprtn[size];
float *ptrRes = &result[size];
while (true) {
cout << "=====CALCULATOR=====\n\n";
cout << "ENTER TWO NUMBERS:" << endl;
while (!(cin >> *ptrf >> *ptrs)) {
system("cls");
cout << "INVALID INPUT. PLEASE ENTER TWO NUMBERS:\n";
cin.clear();
cin.ignore(2);
}
cout << endl;
do {
cout << "Choose Operation to be Used: \n"
<< " + --- Addition \n"
<< " - --- Subtraction \n"
<< " * --- Multiplication \n"
<< " / --- Division \n"
<< " % --- Remainder \n";
cout << "Answer: ";
cin >> answer;
cout << endl;
switch (answer) {
case '+':
cout << "ADDITION\n";
break;
case '-':
cout << "SUBTRACTION\n";
break;
case '*':
cout << "MULTIPLICATION\n";
break;
case '/':
cout << "DIVISION\n";
break;
case '%':
cout << "REMAINDER\n";
break;
default:
answer = false;
system("cls");
cout << "PLEASE ENTER A VALID ANSWER. CHOOSE BELOW.\n\n";
cout << "FIRST NUMBER: " << *ptrf << endl;
cout << "SECOND NUMBER: " << *ptrs;
cout << endl << endl;
continue;
}
} while (!answer);
cout << "DO YOU WANT TO TRY AGAIN? (Y / N): ";
cin >> answer;
switch (answer) {
case 'Y':
case 'y':
system("cls");
continue;
default:
cout << "VIEW HISTORY? (Y / N): ";
cin >> answer;
switch (answer) {
case 'Y':
case 'y':
cout << "HISTORY\n\n";
break;
default:
return 0;
}
}
}
}
This is not valid C++ code:
int size = 1, fNum[size], sNum[size]; // wrong: C++ forbids Variable Length Arrays (1)
char oprtn[size], answer; // ditto...
;
float result[size]; // ditto...
int *ptrf = &fNum[size]; // wrong: this syntax makes ptrf points one past end of array (2)
int *ptrs = &sNum[size]; // ditto...
char *ptro = &oprtn[size]; // ditto...
(1): VLA are a C language concept. Some compilers (gcc and CLang) allow it as an extension but it is useless in C++ because of the containers from the standard library
(2): the idiomatic way to initialize a pointer to the beginning of an array is just int *ptrf = Num; When used as a rvalue (in short at the right side of an = sign), an array decays to a pointer to its first element. So it reads (int *) ptr = &(fNum[0]);: ptr is a pointer to int and its initial value is the address of the first element of the array fNum
fNum[size]
is an array of one integer.
int *ptrf = &fNum[size];
Is a pointer to one past the last element of this array, therefore it's out of bounds access, this is undefined behaviour.
Since it only has one element, you declaring it as an array is pointless.
A pointer to the beginning of an array would be:
int *ptrf = fNum;
Or
int *ptrf = &fNum[0];
You can then cycle trough the array incrementing the pointer ptrf++.
To assing a pointer to a variable:
int x;
int *ptr = &x;
So the variable declarations and assignments:
int size = 1, fNum[size], sNum[size];
char oprtn[size], answer;
float result[size];
int *ptrf = &fNum[size];
int *ptrs = &sNum[size];
char *ptro = &oprtn[size];
float *ptrRes = &result[size];
Are the same as:
int fNum, sNum;
char oprtn, answer;;
float result;
int *ptrf = &fNum;
int *ptrs = &sNum;
char *ptro = &oprtn;
float *ptrRes = &result;
That said, C++ has mutch nicer data containers you can use like std::vector or std::array.
One last note, variable length arrays(fNum[size]) are forbidden in C++.
Related
I have a simple program that calculates for mpg using arrays and pointers
When I input miles, it works perfectly but when i input gallons I can only input until 5th. any advice?
At first when it was still a for loop it was until 3rd only but when i used try and catch it was until 5th
I tried changing ctr value after the first for loop where i inputted miles but it didnt change. I tried using do while and while loop and still
const int size = 10;
typedef double *pointers;
void Mperg();
void MilesPerrGallon(double *ptr1, double *ptr2);
char displayMenu(char *pt);
int main()
{
char sagot;
char *ptr;
ptr =& sagot;
displayMenu(ptr);
switch(sagot){
case '1':
Mperg();
break;
case '2':
cout << "toit";
break;
default:
cout << sagot << " is invalid";
break;
}
}
void Mperg(){
double miles[size], gallons[size];
int ctr;
pointers milPtr, galPtr;
system("cls");
cout<<"COMPUTING FOR MPG : miles per gallon...\n";
cout<<"MILES\n";
galPtr = &gallons[size];
milPtr = &miles[size];
for(ctr = 0; ctr<size; ctr++){
try{
cout << "miles[" << ctr << "]: ";
cin >> milPtr[ctr];
if(milPtr[ctr] < 100 || milPtr[ctr] > 250){
throw milPtr[ctr];
}
}
catch(double xmilPtr){
cout << milPtr[ctr] << " is invalid!.. 100-250 only\nreenter new value\n";
ctr--;
}
}
system("cls");
do{
for(ctr = 0; ctr<size; ctr++){
try{
cout << "gallons[" << ctr << "]: ";
cin >> galPtr[ctr];
if(galPtr[ctr] < 5 || galPtr[ctr] > 25){
throw galPtr[ctr];
}
}
catch(double xgalPtr){
cout << galPtr[ctr] << " is invalid!.. 5-25 only\nreenter new value\n";
ctr--;
}
}
}while(ctr<size);
}
char displayMenu(char *pt)
{
//add code here
cout << "---------O P T I O N S---------\n";
cout << "[1] Compute Miles Per Gallon" << endl;
cout << "[2] Sorting of Numbers" << endl;
cout << "[3] EXIT" << endl;
cout << "-------------------------------\n";
cout << "Enter your choice: ";
cin >> *pt;
return *pt;
}
Miles
Gallons
galPtr = &gallons[size];
milPtr = &miles[size];
Since size is 10, this:
Sets galPtr to point to the 11th element of gallons.
Set milPtr to point to the 11th element of miles.
That's what the above code means in C++.
Of course, both arrays have only ten values, and attempting to obtain a pointer and using the pointer to modify the 11th, and subsequent, values in both arrays is undefined behavior.
You obviously meant to implement galPtr=gallons and milPtr=miles, here, although there is no real reason to use pointers this way, it doesn't accomplish anything.
I am learning the basics of C++. The code is working fine as I wanted, but what I want to know is in case 2 where the function is to swap the strings, what is basically going on? Is the string at array[pos1 -1] being copied to temp and then swapped or just the addresses of the strings to be swapped are being reallocated?
#include <iostream>
using namespace std;
int main()
{
const char *array[] {"Albert",
"Newton",
"Gallilio",
"Hawking"};
cout << "What do you want to do:\n1-Display Strings\n2-Swap Positions" << endl;
unsigned short int choice{};
cin >> choice;
switch (choice)
{
case 1:
{
for (short int i = 0; i < _countof(array); i++)
{
cout << "\n" << array[i];
}
cout << endl;
break;
}
case 2:
{
short int pos1{}, pos2{};
const char *temp{ nullptr };
cout << "Whom do you want to swap? Enter two numbers when prompted: " << endl;
cout << "Swap --- "; cin >> pos1;
cout << "With --- "; cin >> pos2;
temp = array[pos1 - 1];
array[pos1 - 1] = array[pos2 - 1];
array[pos2 - 1] = temp;
cout << "\nChanged Order is";
for (short int i{} ; i < _countof(array); i++)
{
cout << "\n" << array[i];
}
cout << endl;
break;
}
default:
cout << "\a";
}
return 0;
}
Let's assume pos1 is 1 and pos2 is 2.
Then array[pos1-1] holds a pointer to a character A that is interpreted as a string of characters Albert\0 terminated by a null. Likewise array[pos2-1] holds a pointer to the string Newton\0.
When case 2 is hit, temp is initialized to hold a null pointer. Then temp is assigned to hold a copy of the pointer to Albert\0. Then array[pos1-1] is reassigned to hold a pointer to Newton\0. We then want array[pos2-1] to point to Albert\0, but the pointer value in array[pos1-1] doens't point there anymore. That's where the copy in temp comes in, because it is still a pointer to Albert\0, so this pointer is copied to array[pos2-1].
I am having this problem with my calculator I made. See, when I type in a calculation it always adds a 0 to the end. I don't know how to fix this do you have any ideas?
Here's the code:
#include <iostream>
using namespace std;
void Input(float &x, float &y);
float a = 1.0, b = 1.0, result;
char op;
int main() {
cout << "Welcome to Foxy's calculator" << endl;
cout << "----------------------------" << endl;
cout << "Please input a calculation operation (eg. 1+1): ";
cin >> a >> op >> b;
Input(a, b);
cout << result << endl;
system("pause");
return 0;
}
void Input (float &x, float &y) {
a = x;
b = y;
switch (op)
{
case '+':
cout << x + y;
break;
case '-':
cout << x - y;
break;
case '*':
cout << x*y;
break;
case '/':
cout << x / y;
break;
default:
cout << "Error! Operator is not correct" << endl;
cout << "Please input your calculation with a proper operator: ";
cin >> a >> op >> b;
}
}
result is a global static variable that gets zero - initialized and is never changed. So cout << result << endl; will always print "0". To fix this you should make a, b, result and op local to main (global variables are bad), pass a, b andop to calculating function and store returned calculation result in result. It will look something like this:
float result = Input(a, b, op);
cout << result << endl;
You call cout << result << endl; in the caller. and result is always 0. This is because it is never explicitly set to anything and the C++ compiler kindly zero-initialises it since it's at global scope.
In such instances, your line by line debugger is your best friend. The fact that you've mashed up your 1) input, 2) calculation, and 3) output stages is not helping: ideally they should all be separate parts of your program.
Remove cout << result << endl;
I am new to c++ and and am working on a program that has is a simple dvd rental program. I am having issues with case 3 & 4 specifically. Maybe I am misunderstanding the purpose behind sizeof. What I am trying to have it do is tell if the char array is empty and if it is allow the user to check it out by putting their name in and if it is not available give them a response saying that it is not available. case 4 should do the opposite and allow them to check it in. Any suggestions would be greatly appreciated.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <limits>
using namespace std;
const int arrSize = 5;
struct dvdStruct //distance struct
{
int id;
char title[51] = { 0 };
char rating[5] = { 0 };
double price;
char borrower[51] = { 0 };
} dvd;
dvdStruct dvds[arrSize] = {};
int userSelection; //intput variable for main menu selection
int borrowId (0);
int borrowIdReturn(0);
//void initalize();
int main() {
int size(0);
dvds[0].id = 1;
dvds[1].id = 2;
dvds[2].id = 3;
dvds[3].id = 4;
dvds[4].id = 5;
strcpy(dvds[0].title, "Fast 1");
strcpy(dvds[1].title, "Fast 2");
strcpy(dvds[2].title, "Fast 3");
strcpy(dvds[3].title, "Fast 4");
strcpy(dvds[4].title, "Fast 5");
strcpy(dvds[0].rating, "PG - 13");
strcpy(dvds[1].rating, "PG - 13");
strcpy(dvds[2].rating, "PG - 13");
strcpy(dvds[3].rating, "PG - 13");
strcpy(dvds[4].rating, "PG - 13");
dvds[0].price = '19.1';
dvds[1].price = '19.2';
dvds[2].price = '19.3';
dvds[3].price = '19.4';
dvds[4].price = '19.5';
strcpy(dvds[0].borrower, "");
cout << strlen(dvds[0].borrower) << endl;
strcpy(dvds[1].borrower, "\0");
strcpy(dvds[2].borrower, "\0");
strcpy(dvds[3].borrower, "\0");
strcpy(dvds[4].borrower, "\0");
do {
cout << "1.Display All DVD’s" << endl << "2.Display DVD Detail" << endl << "3.Check Out a DVD" << endl << "4.Check In a DVD" << endl << "5.Exit" << endl;
cin >> userSelection; //Input from the user.
switch (userSelection)
{
case 1:
for (int i = 0; i < arrSize; i++)
{
std::cout << dvds[i].title << "' " << dvds[i].rating << " " << dvds[i].borrower << endl;
}
system("pause");
system("CLS");
break;
case 2:
int dvdNum;
cout << "Enter a DVD number:";
cin >> dvdNum;
std::cout << dvds[dvdNum - 1].title << "' " << dvds[dvdNum - 1].rating << endl;
system("pause");
system("CLS");
break;
case 3:
cout << "Enter and id:";
cin >> borrowId;
if (strlen(dvds[borrowId-1].borrower) == 0)
{
cout << "Enter your name: ";
cin >> dvds[borrowId-1].borrower;
}
else
{
cout << "This dvd is not available" << endl;
}
system("pause");
system("CLS");
break;
case 4:
cout << "Enter and id:";
cin >> borrowIdReturn;
if (strlen(dvds[borrowIdReturn - 1].borrower) == 0)
{
cout << "This dvd is available" << endl;
}
else
{
cout << "Your DVD has been returned " << endl;
strcpy(dvds[borrowIdReturn - 1].borrower, "\0");
}
system("pause");
system("CLS");
break;
case 5:
return 0;
break;
}
} while (userSelection == 1 || userSelection == 2 || userSelection == 3 || userSelection == 4);
}
sizeof() gives you the size of an object. The size of the object is always the same, no matter what's in the object. In fact, sizeof() is calculated at compile time, and its value could not be affected, in any way, by whatever happens at runtime.
C++ code should use std::string, instead of char arrays, in most cases. std::string's empty() method indicates whether the string is empty.
If you still insist on working with C-style char arrays, and C-style '\0' terminated strings, use the C strlen() function to check if the character array contains nothing but a leading '\0', indicating an empty string.
As part of a school assignment, I need to build a modular calculator with at least four modules (getData, getInteger, processData, displayData) doing add/subtract/multiply/divide/modulus operations on two integers.
I'm getting pretty stumped on putting this thing together, and I think it's largely because I'm struggling to understand how inter-function calls work (e.g. one function sending information to another function).
I've got the getInteger function getting integer input from the user, and I'm using processdata(intA, intB); to send this to the processData(int, int) function; but my getData(int) function also needs to send an integer input to processData - however processData(select) isn't valid because it doesn't have enough arguments. (I don't really understand what this means)
This is probably a bit confusing, so I've got the whole (unfinished/wip/doesn't actually work) program here:
//calculator program
//4 modules required: getData, getInteger, processData, displayData
#include <iostream> //To input/output to the display (I think)
#include <conio.h> //For getch() at end of program
using namespace std;
//prototypes
void getInteger(int, int);
void getData(int);
void processData(int, int);
void displayData(); // haven't added anything yet
int main(){
//prevents window from immediately closing
getch();
return 0;
}
void getInteger(int, int) {
int intA, intB;
cout << "Please enter integer one: " << endl;
cin >> intA;
cout << "Please enter integer two: " << endl;
cin >> intB;
processData(intA, intB); //sends info to processData function
}
void getData(int) {
int select;
cout << "Available Functions" << endl;
cout << "1. Addition (+)" << endl;
cout << "2. Subtraction (-)" << endl;
cout << "3. Multiplication (*)" << endl;
cout << "4. Division (/)" << endl;
cout << "5. Modulus (%)" << endl;
cout << "Please type your selection (1-5): " << endl;
cin >> select;
if (select > 5 || select < 1) {
cout << "Error: Out of Bounds, please re-enter your selection: " << endl;
cin >> select;
}
processData(select); //sends info to processData function
}
void processData() {
int add, sub, mul, div, mod, select, intA, intB;
switch(select) {
case 1:
select = 1; //addition
add = (intA + intB);
displayData(add); //sends info to displayData function
break;
case 2:
select = 2; //subtraction
sub = (intA - intB);
displayData(sub);
break;
case 3:
select = 3; //multiplication
mul = (intA * int B);
displayData(mul);
break;
case 4:
select = 4; //division
div = (intA / intB);
displayData(div);
break;
case 5:
select = 5; //modulus
mod = (intA % intB);
displayData(mod);
break;
default:
cout << "There's been an error :(" << endl;
}
return 0;
}
void displayData() {
}
Am I doing this all backwards? I feel like it'd be a lot easier if I could contain this in fewer functions, but it's mandatory to keep it in (at least) 4.
Your declarations and definitions are not matching with the arguments that you are passing. i.e. void processData() is in your definition, but you declare it void processData(int, int);
The traditional approach for this problem is to collect all the data needed in some way, then call the function to do the work. For your case, you'd have to figure out the select value, and then the intA and intB values [1], then pass all three into processData.
The other opption is to chain the calls together, so ask for the select value first, then pass the select to the function that reads the data, and call the processData from there.
So you would end up with something like this:
void getInteger(int select)
{
cout << "Please enter integer one: " << endl;
cin >> intA;
cout << "Please enter integer two: " << endl;
cin >> intB;
processData(select, intA, intB);
}
void processData(int select, int intA, int intB)
{
... code goes here...
}
I'm intentionally NOT writing the complete code - the way to learn programming is to DO things for yourself. Copy-n-paste is something you probably already can do.
[1] This is a bit problematic, a function can only return one thing. Since you have two different values to return, that's not going to work. An experienced programmer would either use reference-arguments, or return a structure containing both values, but my guess is that's part of what you are learning in a future lesson, so let's skip that idea.
Here is a working version of your code... Take note of the changes and also take notice to the use of pointers in getInteger(int*,int*)
Hope this helps you out!
#include <iostream> //To input/output to the display (I think)
#include <conio.h> //For getch() at end of program
using namespace std;
//prototypes
void getInteger(int*,int*);
void getData();
void processData(int, int, int);
void displayData(int); // haven't added anything yet
int main(){
getData();
return 0;
}
void getInteger(int *ptrA, int* ptrB) {
*ptrA = 0; //safety
*ptrB = 0; //safety
int tempA = 0;
int tempB = 0;
cout << "Please enter integer one: " << endl;
cin >> tempA;
cout << "Please enter integer two: " << endl;
cin >> tempB;
*ptrA = tempA;
*ptrB = tempB;
}
void getData() {
int select = 100;
while(select != 0){
cout << "Available Functions" << endl;
cout << "0. Exit program" << endl;
cout << "1. Addition (+)" << endl;
cout << "2. Subtraction (-)" << endl;
cout << "3. Multiplication (*)" << endl;
cout << "4. Division (/)" << endl;
cout << "5. Modulus (%)" << endl;
cout << "Please type your selection (1-5): " << endl;
cin >> select;
if (select > 5 && select > 0) {
cout << "Error: Out of Bounds, please re-enter your selection: " << endl;
cin >> select;
}else if(select == 0){
break;
}
int intA, intB; //these are set in the following void
getInteger(&intA, &intB);
processData(intA, intB, select); //sends info to processData function
}
}
void processData(int intA, int intB, int select) {
int add, sub, mul, div, mod;
switch(select) {
case 1:
select = 1; //addition
add = (intA + intB);
displayData(add); //sends info to displayData function
break;
case 2:
select = 2; //subtraction
sub = (intA - intB);
displayData(sub);
break;
case 3:
select = 3; //multiplication
mul = (intA * intB);
displayData(mul);
break;
case 4:
select = 4; //division
div = (intA / intB);
displayData(div);
break;
case 5:
select = 5; //modulus
mod = (intA % intB);
displayData(mod);
break;
default:
cout << "There's been an error :(" << endl;
}
// return 0; void does not return
}
void displayData(int result){
cout << "The result is: " << result << endl;
}