So its a Friday, Ive been working this app and my head is about to explode. I can't find the problem anywhere!!! I am a beginner coder so I am hoping the gods of stackoverflow can guide me in the right direction or provide some feedback!! :]
This console app is just a simple parking time ticket. The code complies fine with no errors. But my math is all messed up!
Here is a sample result: With time entered as 3:50 and exit 5:29 with vehicle as T.
TIME-IN -858993460:858993460
TIME-OUT -858933460:-858993460
PARKING TIME 0:-858993460
TOTAL CHARGE -214748352.00
And here is my code
#include <iostream> //used for cout/cin
#include <iomanip> //used to manipulate data
void getData(int* ehour, int* emin, int* exhour, int* exmin);
void rate(int exhour, int exmin, int ehour, int emin, int* thour, int* tmin, int* round);
void charge(char* vehic, float* rate1, float* rate2, int ehour);
void result(int exhour, int exmin, int ehour, int emin, int thour, float rate1, float rate2, int round, float total);
int main(void)
{
char vehic;
int ehour;
int emin;
int exhour;
int exmin;
int thour;
int tmin;
int round;
float rate1;
float rate2;
float total;
getData(&ehour, &emin, &exhour, &exmin);
rate(exhour, exmin, ehour, emin, &thour, &tmin, &round);
charge(&vehic, &rate1, &rate2, ehour);
total= rate1 + rate2;
result( exhour, exmin, ehour, emin, thour, rate1, rate2, round, total);
return 0;
}
void getData(int* ehour, int* emin, int* exhour, int* exmin)
{
char v;
printf("Enter C for car, B for bus, T for truck: ");
scanf("%c", &v);
printf("\nHour vehicle entered 0-24: ");
scanf("%d", &ehour);
printf("\nMinute vehicle entered 0-60: ");
scanf("%d", &emin);
printf("\nHour vehicle exited 0-24: ");
scanf("%d", &exhour);
printf("\nMinute vehicle exited 0-60: ");
scanf("%d", &exmin);
return;
}
void rate(int exhour, int exmin, int ehour, int emin, int* thour, int* tmin, int* round)
{
if(emin < exmin)
{
emin= emin + 60;
exhour= exhour - 1;
}
*thour = ehour - exhour;
*tmin = emin - exmin;
if ((*tmin > 0 && *tmin <= 60))
{
*thour = *thour + 1;
*round = *tmin * 0;
}
return;
}
void charge(char* vehic, float* rate1, float* rate2, int ehour)
{
switch (*vehic)
{
case 'c': if (ehour <= 3)
{
*rate1 = 0.00;
if (ehour > 3)
*rate2 = 1.25 * (ehour - 3);
}
break;
case 'b': if (ehour <= 2)
{
*rate1 = 2.00 * ehour;
if (ehour > 2)
*rate2 = 2.50 * (ehour - 2);
}
break;
case 't': if (ehour <= 1)
{
*rate1 = 3.75 * ehour;
if (ehour > 1)
*rate2 = 4.50 * (ehour - 1);
}
break;
}
return;
}
void result(int exhour, int exmin, int ehour, int emin, int thour, float rate1, float rate2, int round, float total)
{
printf("\n\t\t PARKING LOT CHARGE \t\t\n");
printf("\nType of vehicle: Car or Bus or Truck");
printf("\nTIME-IN\t\t %d:%d", ehour, emin);
printf("\nTIME-OUT\t\t %d:%d", exhour, exmin);
printf("\n\t\t\t --------");
printf("\nPARKING TIME\t\t %d:%d", thour, round);
printf("\n\t\t\t --------");
total= rate1 + rate2;
printf("\nTOTAL CHARGE\t\t %4.2f\n\n", total);
return;
}
I am sorry this is alot of code! I am just so puzzled!!! Are my ints not formatted correctly? Is the math wrong?
char v;
printf("Enter C for car, B for bus, T for truck: ");
scanf("%c", &v);
printf("\nHour vehicle entered 0-24: ");
scanf("%d", ehour);
printf("\nMinute vehicle entered 0-60: ");
scanf("%d", emin);
printf("\nHour vehicle exited 0-24: ");
scanf("%d", exhour);
printf("\nMinute vehicle exited 0-60: ");
scanf("%d", exmin);
You took the address of the parameters, which were already pointers.
As a general finger exercise, here's what you could do in more typical C++ style:
/////////////////////////////////////
// timepoint classes (booking.hpp)
struct timepoint
{
int hour, minute;
timepoint normalized() const;
int totalMinutes () const;
int roundedHours () const;
timepoint operator- (timepoint const& rhs) const;
};
struct booking_t
{
char vehicle;
timepoint enter, exit;
timepoint parked() const { return exit - enter; }
};
/////////////////////////////////////
// main program (main.cpp)
booking_t inputData();
void displayBill(booking_t const& booking);
int main(void)
{
auto booking = inputData();
displayBill(booking);
}
/////////////////////////////////////
// timepoint methods (booking.cpp)
timepoint timepoint::normalized() const
{
timepoint tmp { (hour + minute/60) % 24, minute % 60 };
while (tmp.minute < 0) tmp.hour--, tmp.minute+=60;
while (tmp.hour < 0) tmp.hour+=24;
return tmp;
}
int timepoint::roundedHours() const
{
return (totalMinutes()-1) / 60 + 1; // TODO check rounding logic
}
int timepoint::totalMinutes() const
{
return hour*60 + minute;
}
timepoint timepoint::operator-(timepoint const& rhs) const
{
return timepoint { 0, totalMinutes() - rhs.totalMinutes() } .normalized();
}
#include <iostream> //used for cout/cin
timepoint getTime(std::string label)
{
int hour, minute;
std::cout << "\nHour " << label << " 0-24: ";
std::cin >> hour;
std::cout << "\nMinute " << label << " 0-60: ";
std::cin >> minute;
return { hour, minute };
}
/////////////////////////////////////
// global functions - input
booking_t inputData()
{
std::cout << "Enter C for car, B for bus, T for truck: ";
char v;
std::cin >> v;
auto entered = getTime("vehicle entered");
auto exited = getTime("vehicle exited");
return { v, entered.normalized(), exited.normalized() };
}
/////////////////////////////////////
// calculation + billing
#include <sstream>
#include <iomanip> //used to manipulate data
#include <map>
static std::ostream& operator <<(std::ostream& os, timepoint const& tp)
{
std::ostringstream oss;
oss << std::setw(2) << std::setfill('0') << tp.hour << ':'
<< std::setw(2) << std::setfill('0') << tp.minute;
return os << oss.str();
}
std::pair<float,float> charge(booking_t const& booking)
{
struct tariff_t { int threshold; float rate1, rate2; };
const static auto tariffs = std::map<char, tariff_t> {
{ 'c', { 3, 0 , 1.25 } },
{ 'b', { 2, 2. , 2.5 } },
{ 't', { 1, 3.75, 4.5 } } ,
};
auto& tariff = tariffs.at(std::tolower(booking.vehicle));
auto parked = booking.parked().roundedHours();
return std::make_pair(
tariff.rate1 * std::min(tariff.threshold, parked) ,
tariff.rate2 * std::max(0, parked - tariff.threshold));
}
void displayBill(booking_t const& booking)
{
std::cout << "\n\n PARKING LOT CHARGE\n";
std::cout << "Type of vehicle: Car or Bus or Truck\n";
std::cout << "TIME-IN " << booking.enter << "\n";
std::cout << "TIME-OUT " << booking.exit << "\n";
std::cout << " " << "--------\n";
std::cout << "PARKING TIME " << booking.parked() << "\n";
std::cout << " ROUNDED " << booking.parked().roundedHours() << "\n";
std::cout << " " << "--------\n";
auto rates = charge(booking);
float total = rates.first + rates.second;
std::cout << "TOTAL CHARGE " << std::fixed << std::setw(7) << std::setprecision(2) << total << "\n\n";
}
I can't find much redeeming about your original code, so this isn't an answer per se, but perhaps you might find it interesting how I would write code for your problem in "pure C++":
#include <string>
#include <iostream>
#include <sstream>
bool parse_time(std::string const & s, int & t)
{
int h, m;
char c;
std::istringstream iss(s);
if (iss >> h >> c >> m >> std::ws && c == ':' && iss.get() == EOF)
{
t = 60 * h + m;
return true;
}
return false;
}
int main()
{
int t_in, t_out;
std::string line;
if (!(std::cout << "Enter arrival time: " &&
std::getline(std::cin, line) &&
parse_time(line, t_in) &&
std::cout << "Enter departure time: " &&
std::getline(std::cin, line) &&
parse_time(line, t_out)))
{
std::cerr << "Input error! Aborting.\n";
return 0;
}
std::cout << "You spent " << t_out - t_in << " minutes.\n";
}
Here's a typical session:
Enter arrival time: 5:14
Enter departure time: 8:41
You spent 207 minutes.
One thing I noticed — You pass &ehour and friends, which is a pointer to pointer to your scanf call (you can start by removing & from scanf calls when ehour is int*).
Take out the & in scanf! They are already pointers!
The other error in your code is that the variable vehic never gets a value. It looks like you meant to give it a value in getData but messed that up somehow.
Rule 1: Declare variables near to where you first use them. And initialize all variables when you create them:
int main(void)
{
int ehour = 0;
int emin = 0;
int exhour = 0;
int exmin = 0;
getData(&ehour, &emin, &exhour, &exmin);
int thour = 0;
int tmin = 0;
int round = 0;
rate(exhour, exmin, ehour, emin, &thour, &tmin, &round);
char vehic = 0;
float rate1 = 0;
float rate2 = 0;
charge(&vehic, &rate1, &rate2, ehour);
float total = 0;
total= rate1 + rate2;
result( exhour, exmin, ehour, emin, thour, rate1, rate2, round, total);
return 0;
}
Now see that float total? Move the declaration and initialization of the variable to the same line:
float total = rate1 + rate2;
Rule 2: Don't use pointers if you don't need to. If you have an integer you want to pass both into and out of a function, make the parameter a reference parameter like this:
void getData(int& ehour, int& emin, int& exhour, int& exmin)
In main:
getData(ehour, emin, exhour, exmin);
In getData:
void getData(int& ehour, int& emin, int& exhour, int& exmin)
{
char v;
printf("Enter C for car, B for bus, T for truck: ");
scanf("%c", &v);
printf("\nHour vehicle entered 0-24: ");
scanf("%d", &ehour);
printf("\nMinute vehicle entered 0-60: ");
scanf("%d", &emin);
printf("\nHour vehicle exited 0-24: ");
scanf("%d", &exhour);
printf("\nMinute vehicle exited 0-60: ");
scanf("%d", &exmin);
return;
}
Now, I spotted your first screwup. You where reading not to the integers, but to the pointers to the integers. Now that I have made them references (think "aliases" or for the variables passed in), the & operator gets a pointer to the integer, not a pointer to the pointer to the integer!
The next thing you want to do is not to use scanf. Scanf is hard to use. Why use something hard to use?
Step 3: Your program should help you debug it.
When you read something from input, repeat it back out to make sure you read it right. Ie, after you call getData, the very next thing you should do is repeat out what you read. Eventually when your code is solid you can remove that "repeat it back", but when developing a program this kind of feedback is essential.
See Kerrek SB for better ways to read instead of using scanf.
Related
I got a task in which I receive babies' firstname and weight in kilogram in a character array (for example: Johnny, 2 kg). I must store them in an array that can hold maximum 1000 elements and must be a struct type, storing the baby's firstname and weight.
Every actions must be done in functions - however, when I tried to get the name until the comma, str.copy() didn't work for me. Its specific problem was something with the last parameter, the position. Could someone help me out with that? Also, I'm kinda new to C++ and imagining how to separately, in two functions ask in the char arrays until empty line and do the copying in the other... if someone could help me out, I'd be grateful for that ^^'
Thanks for the help in advance!
#include<iostream>
#include<string>
#define M 1000
struct baby{
std::string baby_name;
float weight;
};
int readIn(baby* baby_datapair, int max);
// int maxWeight(baby* baby_datapair);
// int minWeight(baby* baby_datapair);
// void descendingOrder(baby* baby_datapair, int num);
int main(){
baby baby_array[M];
int n = readIn(baby_array, M);
return 0;
}
int readIn(baby* baby_datapair, int max){
int n = 0;
char name[12];
while (n < max){
std::cout << "Baby" << n+1 << "'s datas (Nickname, weight in kg): ";
std::getline(std::cin, name);
//~ std::cin.ignore(1);
if (neve == ""){
std::cout << "Wrong input!\n";
break;
}else{
std::size_t pos = name.find(',');
std::size_t until = name.copy(baby_datapair[n].baby_name, 0, pos);
}
n++;
}
return n;
}
// int maxWeight(baby* baby_datapair){
// }
// int minWeight(baby* baby_datapair){
// }
// void descendingOrder(baby* baby_datapair, int num){
// }
You must use std::string name; instead of char name[12]; as std::getline 's parameter. BTW, It make better for memory management. After input data, check pos value for valid value.
#include<iostream>
#include<string>
#define M 1000
struct baby {
std::string baby_name;
float weight;
};
int readIn(baby* baby_datapair, int max);
// int maxWeight(baby* baby_datapair);
// int minWeight(baby* baby_datapair);
// void descendingOrder(baby* baby_datapair, int num);
int main() {
baby baby_array[M];
int n = readIn(baby_array, M);
return 0;
}
int readIn(baby* baby_datapair, int max) {
int n = 0;
//char name[12];
std::string name;
while (n < max) {
std::cout << "Baby" << n + 1 << "'s datas (Nickname, weight in kg): ";
std::getline(std::cin, name);
//~ std::cin.ignore(1);
if (name == "") {
std::cout << "Wrong input!\n";
break;
}
else {
std::size_t pos = name.find(',');
if (pos <= 0) {
std::cout << "Invalid input structure!\n";
continue;
}
//std::size_t until = name.copy(baby_datapair[n].baby_name, 0, pos);
baby_datapair[n].baby_name = name.substr(0, pos);
baby_datapair[n].weight =(float)atof(name.substr(pos+1).c_str());
//std::cout << std::endl;
//std::cout << baby_datapair[n].baby_name;
//std::cout << ", " << baby_datapair[n].weight;
}
n++;
}
return n;
}
// int maxWeight(baby* baby_datapair){
// }
// int minWeight(baby* baby_datapair){
// }
// void descendingOrder(baby* baby_datapair, int num){
// }
You are taking it the wrong size. You should not try to copy to, but just copy from. BTW, name must be a std::string for you program to compile, and you should check for possible end of file. So a minally fixed version could be:
std::string name;
while (n < max) {
std::cout << "Baby" << n + 1 << "'s datas (Nickname, weight in kg): ";
std::getline(std::cin, name);
//~ std::cin.ignore(1);
if ((! std::cin) || name == "") {
std::cout << "Wrong input!\n";
break;
}
else {
std::size_t pos = name.find(',');
baby_datapair[n].baby_name = std::string(name.c_str(), pos);
baby_datapair[n].weight = strtof(name.c_str() + pos + 1, nullptr);
}
But using a std::stringstream would be more idiomatic in C++. Above code is rather C-ish...
I have 3 files, book.h, book.cpp, bookdriver.cpp. I want to know if the ISBNs in a list are found in the array using binary search.
book.h:
using namespace std;
ofstream fout("output2.txt");
class Book
{
string author; // A string for the name of the author
string title; //A string for the book title
int ISBN; //A long integer for the ISBN
public:
Book(); //A default constructor
void print();
int getISBN() const; //A const function GetISBN that returns the integer containing the ISBN.
int binary_search(Book, int, int, int);
};
book.cpp- also includes print function which uses fout
#include "book.h"
//iterative binary search function, returns location of ISBN in array if present
int Book::binary_search(Book arr[], int x, int n, int ISBN)
{
while (n >= x)
{
int midpt = x + (n - x) / 2;
//if ISBN is in midpoint
if (arr[midpt].getISBN() == ISBN)
{
return midpt;
}
//if ISBN is greater than midpoint, ignore left side of array
if (arr[midpt].getISBN() < ISBN)
{
x = midpt + 1;
}
//if ISBN is smaller, ignore right side of array
else
{
n = midpt - 1;
}
}
//if ISBN not present
return -1;
}
bookdriver.cpp
#include "book.h"
const int num = 10; //number of book objects the array should hold *can be changed*
int main()
{
Book book_array[num] = {}; //array can hold num book objects
for (int c = 0; c < num; c++)
{
book_array[c] = Book();
book_array[c].getData(data); //reading book information
}
//read file
ifstream fin("bookISBN.txt");
int find_ISBN;
while (fin >> find_ISBN)
{
bool match = false;
int count = 0;
int result = binary_search(book_array[10], 0, num - 1, find_ISBN); //error here
if (result == -1) //if ISBN not found
{
fout << "Sorry, the ISBN " << find_ISBN << " is not found." << endl;
}
else
{
fout << "The ISBN " << find_ISBN << " is found in the system!" << endl;
}
count++;
}
return 0;
}
I'm using fout in both book.cpp and bookdriver.cpp so I have ofstream fout (output2.txt) in the header but I'm getting linker errors(Error LNK2005) in vs.
I think because of the one definition rule, fout is defined twice?
Here's a start:
#include <iostream>
#include <fstream>
using namespace std;
const int num = 2;
class Book
{
public:
Book(){};
string author;
string title;
int ISBN = 0;
int data;
};
int binary_search (Book arr[num], int x, int n, int ISBN, int overflow)
{
int mid = (x + n) / 2;
if (x == mid || n == mid)
overflow++;
if (overflow > 100)
return false;
if (arr[mid].ISBN > ISBN)
return binary_search(arr, x , mid, ISBN, overflow);
else if (arr[mid].ISBN < ISBN)
return binary_search(arr, mid, n , ISBN, overflow);
return true;
}
int main() {
ofstream fout("output2.txt");
ifstream fin("bookISBN.txt");
int find_ISBN;
Book book1;
book1.title = "Alice in Wonderland";
book1.author = "C.S. Lewis";
book1.ISBN = 1;
Book book2;
book2.title = "Wuthering Heights";
book2.author = "Emily Bronte";
book2.ISBN = 2;
Book book3;
book3.title = "Moby Dick";
book3.author = "Herman Melville";
book3.ISBN = 25;
Book book_array[num] = {book1, book2};
while (fin >> find_ISBN)
{
int result = binary_search(book_array, 0, num, find_ISBN, 0);
if (result == false)
{
fout << "Sorry, the ISBN " << find_ISBN << " is not found." << endl;
}
else
{
fout << "The ISBN " << find_ISBN << " is found in the system!" << endl;
}
}
fin.close();
fout.close();
return 1;
}
I am writing a very simple game simulator (does not use classes). From the main() function, I successfully access one of my functions, but another function call throws the error: 'No matching function for call to simGame'.
Any ideas why this is happening?
Code:
...
float rollDice() {
default_random_engine randomGenerator(time(NULL));
uniform_real_distribution<float> rollDice(0.0f, 1.0f);
float roll = rollDice(randomGenerator);
return roll;
}
string simGame(string p1, string p2, int p1Health, int p2Health, int p1Attack, int p2Attack) {
// Game State
bool gameOver = false;
float attack = rollDice();
int pl1 = 0;
int pl2 = 1;
int turn = pl1;
int defenderHealth = p2Health;
int attackerAttack = p1Attack;
while ((p1Health > 0) && (p2Health > 0)) {
if (attack > 0.3) {
defenderHealth -= attackerAttack;
}
turn = -turn + 1;
if (turn == 0) {
defenderHealth = p2Health;
attackerAttack = p1Attack;
} else {
defenderHealth = p1Health;
attackerAttack = p2Attack;
}
}
turn = -turn + 1;
if (turn == 0) {
return p1;
} else {
return p2;
}
return 0;
}
int setHealth(int botNum, int botHealth) {
int totalHealth = botNum * botHealth;
return totalHealth;
}
int main() {
// bot types
int drWhosAndCompanions;
int ricksAndMortys;
// Attributes
int rmHealth = 10;
int dcHealth = 15;
int rmAttack = 15;
int dcAttack = 10;
int totalRMHealth;
int totalDocHealth;
cout << "How many Ricks and Mortys?" << endl;
cin >> ricksAndMortys;
cout << "How many Dr Whos and Companions?" << endl;
cin >> drWhosAndCompanions;
// Starting Vals
totalRMHealth = setHealth(ricksAndMortys, rmHealth);
totalDocHealth = setHealth(drWhosAndCompanions, dcHealth);
cout << "You have chosen " << ricksAndMortys << " Ricks and Mortys and " << drWhosAndCompanions << " Dr. Whos and Companions.\n";
string res;
res = simGame(ricksAndMortys, drWhosAndCompanions, rmHealth, dcHealth, rmAttack, dcAttack);
return 0;
}
Its simple
Your function definition has this prototype
simGame(string, string, int, int, int, int);
But you are passing
simGame(ricksAndMortys, drWhosAndCompanions, rmHealth, dcHealth, rmAttack, dcAttack);
In which ricksAndMortys and deWhosAndCompanions are int type
So change their data type to string
In main function
// bot types
int drWhosAndCompanions;
int ricksAndMortys;
Should be
// bot types
string drWhosAndCompanions;
string ricksAndMortys;
in the following code I have a for loop in my main function. Since a function can't return 2 values, what are some ways I could create a function, or functions, to remove it from my main function. Thanks!
#include <iostream>
#include <cmath>
using namespace std;
int getNumberExercises();
int getScores(int numberOfExercises);
int getPoints(int numberOfExercises);
double roundToTenth(double number);
double calcPercentage(int totalScore, int totalPoints);
void getTotal(int totalScore, int totalPoints, double scorePercentage);
int main() {
int numberOfExercises = 0;
int totalScore = 0;
int totalPoints = 0;
double scorePercentage = 0.0;
numberOfExercises = getNumberExercises();
for (int i = 1; i <= numberOfExercises; i++) {
totalScore += getScores(i);
totalPoints += getPoints(i);
}
scorePercentage = calcPercentage(totalScore, totalPoints);
getTotal(totalScore, totalPoints, scorePercentage);
return 0;
}
int getNumberExercises() {
int numberOfExercises;
cout << "How many exercises to input? ";
cin >> numberOfExercises;
cout << endl;
return numberOfExercises;
}
int getScores(int i) {
int score = 0;
cout << "Score received for exercise " << i << ": ";
cin >> score;
return score;
}
int getPoints(int i) {
int points = 0;
cout << "Total points possible for exercise " << i << ": ";
cin >> points;
cout << endl;
return points;
}
double roundToTenth(double number) {
return floor(number * 100 + 0.5) / 100;
}
double calcPercentage(int totalScore, int totalPoints) {
double scorePercentage = (double) totalScore / totalPoints * 100;
return scorePercentage;
}
void getTotal(int totalScore, int totalPoints, double scorePercentage) {
cout << "Your total is " << totalScore << " out of " << totalPoints << ", or " << roundToTenth(scorePercentage) << "%";
}
Either typedef a std::pair to a descriptive name, or create your own type to hold the things you want to return:
using ScorePointPair = std::pair<int, int>; // C++11
typedef std::pair<int, int> ScorePointPair; // pre C++11
Or
struct ScorePointPair
{
int score;
int points;
};
Then simply return this from your function (by value):
ScorePointPair fun()
{
// Loop etc...
return {score, points};
};
I would recommend the custom type (struct/class) approach, as this tends to be more maintainable.
To return multiple values use pass by pointer:
void modify(int *val1, int *val2)
{
*val1 = 46;
*val2 = 100;
}
In caller:
int a, b;
modify(&a, &b);
Now a will be 46, and b will be 100. This is because the address is copied, rather than the actual variable, which is what happens in pass by value.
So if you want to find the number of occurences of tabs and commas in a file:
void findtabcomma(const char *fn, int *ncomma, int *ntab)
{
FILE *fp;
int c;
if (fp = fopen(fn, "r")) {
while ((c = getc(fp)) != EOF) {
if (c == '\t')
++(*ntab);
if (c == ',')
++(*ncomma);
}
fclose(fp);
}
}
You can use the function like this:
int c, t;
findtabcomma(filenam, &c, &t);
printf("Commas: %d\nTabs: %d", c, t);
And in C++, you can use reference variables. So the findtabcomma function could be rewritten as:
void findtabcomma(const char *fn, int &ncomma, int &ntab)
{
FILE *fp;
int c;
if (fp = fopen(fn, "r")) {
while ((c = getc(fp)) != EOF) {
if (c == '\t')
++ntab;
if (c == ',')
++ncomma;
}
fclose(fp);
}
}
And used like this:
int c, t;
findtabcomma(filenam, c, t);
printf("Commas: %d\nTabs: %d", c, t);
Notice how there are no more *s and &s with C++ references.
You can create a function that either returns an array of type int of size 2 such as
int* functionName(arg1, arg2)
array[0] = totalScore;
array[1] = totalPoints;
return array;
or you could pass in the values by reference by doing something like
void functionName(&arg1, &arg2)
What passing by reference does is it passes the ADDRESS of the variable and then modifies the variable directly instead of creating a copy and passing it into the function.
You can use reference in the argument list to return data
int fun(); can be coded as void fun(int& )
i have homework, but it is not working. Best i can guess as to why it is not working is an auto breakpoint to vs2013 which displays this in the output box.
HEAP[hw2_ccc.exe]: Invalid allocation size - 10 (exceeded fffdefff)
First-chance exception at 0x000007FEFD9D940D in hw2_ccc.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x000000000012F350.
HEAP[hw2_ccc.exe]: Invalid allocation size - 1 (exceeded fffdefff)
First-chance exception at 0x000007FEFD9D940D in hw2_ccc.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x000000000012CE40.
First-chance exception at 0x000007FEFD9D940D in hw2_ccc.exe: Microsoft C++ exception: [rethrow] at memory location 0x0000000000000000.
First-chance exception at 0x000007FEFD9D940D in hw2_ccc.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x000000000012CE40.
A buffer overrun has occurred in hw2_ccc.exe which has corrupted the program's internal state.
Here is my code:
bankAccount.h
#ifndef H_bankAccount
#define H_bankAccount
#include <string>
#include <iostream>
using namespace std;
class bankAccount
{
public:
void setAccountName(string holderName);
void setAccountNumber(int accountNumber);
void setInterestRate(double interestRate);
void setAccountType(string accountType);
void depositBalance(double deposit);
void withdrawBalance(double withdraw);
void printAccountInformation();
void newAccount(string holderName, int accountNumber, string accountType, double interestRate);
string getAccountName();
bankAccount();
~bankAccount();
private:
string holderName;
int accountNumber;
string accountType;
double balance;
double interestRate;
};
#endif
bankAccount.cpp
#include "bankAccount.h"
using namespace std;
bankAccount::bankAccount()
{
}
bankAccount::~bankAccount()
{
}
void bankAccount::newAccount(string holderName, int accountNumber, string accountType, double interestRate)
{
setAccountName(holderName);
setAccountNumber(accountNumber);
setAccountType(accountType);
setInterestRate(interestRate);
}
void bankAccount::setAccountName(string holderName)
{
bankAccount::holderName = holderName;
}
void bankAccount::setAccountNumber(int accountNumber)
{
bankAccount::accountNumber = accountNumber;
}
void bankAccount::setAccountType(string accountType)
{
bankAccount::accountType = accountType;
}
void bankAccount::setInterestRate(double interestRate)
{
bankAccount::interestRate = interestRate;
}
void bankAccount::depositBalance(double deposit)
{
bankAccount::balance += deposit;
}
void bankAccount::withdrawBalance(double withdraw)
{
bankAccount::balance -= withdraw;
}
void bankAccount::printAccountInformation()
{
cout << "Account Name: " << bankAccount::holderName << endl;
cout << "Account Type: " << bankAccount::accountType << endl;
cout << "Account Number: " << bankAccount::accountNumber << endl;
cout << "Account Interest Rate: " << bankAccount::interestRate << endl;
cout << "Account Balance :" << bankAccount::balance << endl;
}
string bankAccount::getAccountName()
{
return holderName;
}
main.cpp
#include "bankAccount.h"
using namespace std;
int randAccountNum();
string randAccountType();
int interestRate(string accountType);
bool printAccount(bankAccount accounts[10]);
int main()
{
bankAccount account[10];
string accountNames[10] = { "Bob", "Jack", "Billy", "James", "Kathy", "John", "Jenny", "Penny", "Sue", "Louis" };
string accountType;
int accountNumber;
bool prAcc = true;
for (int i = 0; i < sizeof(account); i++)
{
accountType = randAccountType();
accountNumber = randAccountNum();
account[i].newAccount(accountNames[i], accountNumber, accountType, interestRate(accountType));
}
while (prAcc)
{
prAcc = printAccount(account);
}
system("pause");
return 0;
}
int randAccountNum()
{
int num = rand() % 1000 + 1;
return num;
}
string randAccountType()
{
string str;
int num = rand() % 2 + 1;
if (num = 1)
{
str = "Savings";
}
else {
str = "Checking";
}
return str;
}
int interestRate(string accountType)
{
int ir;
if (accountType == "Savings")
{
ir = 2;
}
else {
ir = 4;
}
return ir;
}
bool printAccount(bankAccount accounts[10])
{
string cont;
bool contL = true;
string accountName;
cout << "Enter account name: ";
cin >> accountName;
cout << endl;
for (int i = 0; i < sizeof(accounts); i++)
{
if (accounts[i].getAccountName() == accountName)
{
accounts[i].printAccountInformation();
}
}
while (contL)
{
cout << "Enter another name? (Yes/No): ";
cin >> cont;
if (cont == "Yes")
return true;
else if (cont == "No")
return false;
else
cout << "Invalid. Please enter Yes or No" << endl;
}
}
Change this statement
for (int i = 0; i < sizeof(account); i++)
to
for (int i = 0; i < sizeof(account) / sizeof(*account); i++)
Also there is error in function
bool printAccount(bankAccount accounts[10]);
In this statement
for (int i = 0; i < sizeof(accounts); i++)
sizeof(accounts) is equal to sizeof( bankAccount * )
You have to declare a second parameter for the size of the array passed to the function.
Take into account that you could use objects of type std::array unstead of the arrays. In this case there would not be such problems with the sizes of the arrays.
In your code:
bankAccount account[10];
...
for (int i = 0; i < sizeof(account); i++)
You have a problem in loop iteration (in particular, in the upper bound).
Your account array contains 10 instances of your bankAccount class.
It's clear that your intent is to iterate through all the array items. For that to work correctly, valid values for the i loop index are 0, 1, 2, 3, ..., 9. So, this would work if sizeof(account) returned 10 (in fact, you use the < operator, to exclude the upper limit of 10, and just stopping one value before, at 9, which is correct).
The problem is that sizeof(account) does return the size in bytes of the account array. This is equivalent to 10 * sizeof(bankAccount), where again sizeof(bankAccount) returns the size in bytes of your bankAccount class. Assuming that your bankAccount class' size is e.g. 40 bytes, then sizeof(account) becomes 10 * 40, i.e. 400 bytes.
So, in this case, in your for loop, your index spans values 0,1,2,3,4,...9, 10,11,12,...399: the values in bold are valid, the next ones are not!
You have what is called a buffer overrun, which is clearly stated in the VC++ compiler's error message:
[...] A buffer overrun has occurred
To fix that problem, you have several options.
For example, to get the proper item count, you can divide the total size (in bytes) of the array, by the size of one of its elements, e.g. the first one, at index 0:
// Count of items in the 'account' array
const int accountCount = sizeof(account) / sizeof(account[0]);
for (int i = 0; i < accountCount; i++)
...
Another option is to use a more modern C++ approach, e.g. using C++11's std::array:
#include <array> // for std::array
...
// Define an array of 10 bankAccount's
std::array<bankAccount, 10> account;
// Note that account.size() is 10!
// i.e., this is the size in *element count* (not in bytes, like sizeof()).
for (int i = 0; i < account.size(); i++)
...