Parallel Arrays in C++ - c++

Trying to create a program that takes a coffee flavor add-in and checks if it's valid using an array.
If valid it uses the array index to gather price information.
I managed to write the code below, but it only works for 1 iteration.
How can alter it so a user can enter: Cream and cinnamon and output the total of each add-in as well as the total price of the cup of coffee? The cup of coffee starts with a base price of $2.00
#include <iostream>
#include <string>
using namespace std;
int main()
{
// Declare variables.
string addIn; // Add-in ordered
const int NUM_ITEMS = 5; // Named constant
// Initialized array of add-ins
string addIns[] = { "Cream", "Cinnamon", "Chocolate", "Amaretto", "Whiskey" };
// Initialized array of add-in prices
double addInPrices[] = { .89, .25, .59, 1.50, 1.75 };
bool foundIt = false; // Flag variable
int x; // Loop control variable
double orderTotal = 2.00; // All orders start with a 2.00 charge
string QUIT = "XXX";
// Get user input
cout << "Enter coffee add-in or XXX to quit: ";
cin >> addIn;
// Write the rest of the program here.
for (x = 0; x < NUM_ITEMS && foundIt == false && addIn != QUIT; x++) {
if (addIn == addIns[x]) {
foundIt = true;
x--;
}
}
if (foundIt == true) {
cout << addIns[x] << " $" << addInPrices[x] <<endl;
cout << "$" << orderTotal + addInPrices[x] <<endl;
}
else {
cout << "Sorry, we do not carry that." <<endl;
cout << "Order total is $ " << orderTotal <<endl;
}
return 0;
}

Don't use parallel arrays - you will mess up maintaining them.
Better options:
Create a struct for your add-ins:
struct Addin {
std::string name;
double price;
}
and use an array (or better yet an std::vector) of those structs.
Another option is to use a map:
std::map<std::string, double> addIns = {
{"Cream", .89},
{"Cinnamon", .25},
// etc.
};
Then you won't need a loop, just a lookup
auto item = addIns.find(addIn);
if(item != addIns.end() {
// do your math here
}

Your program is written to get a single output. For multiple outputs there have to be loops and the not found condition also has to be re-written.
try this
#include <iostream>
#include <string>
using namespace std;
int main()
{
// Declare variables.
const int NUM_ITEMS = 5; // Named constant
string addIn[NUM_ITEMS]; // Add-in ordered
// Initialized array of add-ins
string addIns[] = { "Cream", "Cinnamon", "Chocolate", "Amaretto", "Whiskey" };
// Initialized array of add-in prices
double addInPrices[] = { .89, .25, .59, 1.50, 1.75 };
//bool foundIt = false; // Flag variable
int x, i, j; // Loop control variable
double orderTotal = 2.00; // All orders start with a 2.00 charge
string QUIT = "XXX";
// Get user input
cout << "Enter coffee add-ins followed by XXX to quit: ";
for(i=0; i<NUM_ITEMS; i++) {
cin >> addIn[i];
if(addIn[i] == QUIT) {
i++;
break;
}
}
int foundIt[i];
// Write the rest of the program here.
for(j=0; j<i; j++) {
foundIt[j] = -1;
for(x = 0; x<NUM_ITEMS && foundIt[j] == -1 && addIn[j] != QUIT; x++) {
if (addIn[j] == addIns[x]) {
foundIt[j] = x;
}
}
}
for(j=0; j<i-1; j++) {
cout << addIn[j];
if(foundIt[j] != -1) {
cout << " $" << addInPrices[foundIt[j]] << endl;
orderTotal = orderTotal + addInPrices[foundIt[j]];
}
else {
cout << " - Sorry, we do not carry that." <<endl;
}
}
cout << "$" << orderTotal <<endl;
return 0;
}
Sample Outputs
Enter coffee add-ins followed by XXX to quit: Cream Cinnamon XXX
Cream $0.89
Cinnamon $0.25
$3.14
Enter coffee add-ins followed by XXX to quit: Cream Onion XXX
Cream $0.89
Onion - Sorry, we do not carry that.
$2.89
What I did was made addIn array of srings with NUM_ITEMS size instead of variable. Also, foundIt was made an integer array to keep track of indexes where the items are found in addIns array and -1 if not found.
To only access the items that user has entered in addIn, your QUIT has been made the termination condition in that array.

The structure you are looking for is a while or do/while loop.
To be able to enter "empty" lines use std::getline from.
The structure of your program will then look something like this :
As you can see I have a habit of changing my boolean expressions into functions (predicates). This makes code more readable and predicates reusable in other bits of code.
#include <iostream>
#include <string>
bool is_quit(const std::string& input)
{
return input.length() > 0;
}
bool is_valid_input(const std::string& input)
{
return true; // your own check
}
int main()
{
bool quit = false;
std::string input;
do
{
std::cout << "give input : ";
std::getline(std::cin, input);
quit = is_quit(input);
if (is_valid_input(input) && !quit)
{
std::cout << "ok" << std::endl;
}
} while (!quit);
return 0;
}

Related

LNK2019 & LNK1120 C++ error. Program won't compile - Homework

The program won't compile in Visual Studio Community, I have no idea why. I've looked into the function and can't seem to find an answer. Any help would be appreciated as this is for my module at university. I'm a little new to C++ but have some experience in other languages. I just can't seem to find how to get the program to run. I get the below error codes when compiling:
main.cpp: In function ‘void runGame(std::__cxx11::string*, std::__cxx11::string*, int)’:
main.cpp:115:53: error: cannot convert ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’
to ‘std::__cxx11::string* {aka std::__cxx11::basic_string<char>*}’
for argument ‘1’ to ‘std::__cxx11::string answersGiven(std::__cxx11::string*, std::__cxx11::string*, int, int)’
answersGiven(correctAns[0], wrongAns[0], max, max2);
Here is the Code:
#include<iostream>
#include<string>
using namespace std;
int inputCheck(string menu, int limit); // Validates User Input for topic and difficulty selection.
void runGame(string questions[], string answers[], int level); // Function runs game based on questions.
string modifyQuestion(string q, int mod); // Function modifies question based on difficulty level.
string answersGiven(string correct[], string wrong[], int maxC, int maxW);
int main() {
string questions[3][4] = { // 2D array storing answers. Each row stores a Country.
{ "England", "Wales", "France", "Germany" }, // Stores Europe Questions.
{ "Brazil", "Peru", "Argentina", "Columbia" }, // Stores Additional Questions.
{ "Q1", "Q2", "Q3", "Q4" } // Stores South American Questions.
};
string answers[3][4] = { // 2D array storing answers. Each row stores a city.
{"London", "Cardiff", "Paris", "Berlin"}, // Europe Answers.
{"Brasila", "Lima", "Buenos Aires", "Bogota"}, // South America Answers.
{ "A1", "A2", "A3", "A4" } // Stores additional answers.
};
string topics[3] = { "Capital Cities", "" };
char replay; // Variable to check if the user wants to continue playing.
do {
cout << "Please choose one topic for the quiz:\n";
int choice = inputCheck("1: Europe\n2: South America\n3: Testing", 3); // Gets topic choice via validation function.
cout << "\nNow Select a Difficulty:\n";
int difficulty = inputCheck("1: Easy\n2: Medium\n3: Hard", 3); // Gets difficulty choice via validation function.
choice--;
// run the game
runGame(questions[choice], answers[choice], difficulty);
// Checks if user wants to replay game.
cout << "Do you want to play again? Press (Y) to replay: ";
cin >> replay; // Grabs input from user.
replay = toupper(replay); // Sets data to upper case.
} while (replay == 'Y');
return 0;
}
int inputCheck(string menu, int limit) {
cout << menu << endl; // Presents menu of options.
int num; // Variable to store user's input.
cin >> num; // gets user's input.
while (cin.fail() || num < 1 || num > limit) {
cout << "Invalid Input..." << endl; // Outputs error message.
cout << menu << endl; // Presents menu again.
cin.clear(); // Clearsinput error glag.
cin.ignore(1000, '\n'); // Ignores previous inputted data.
cin >> num; // grabs input again.
}
return num;
}
void runGame(string questions[], string answers[], int level) {
string correctAns[] = {};
string wrongAns[] = {};
cin.ignore(1000, '\n'); // Ignore any trailing enter keys in input stream.
int lives = 3; // Stores the amount of users lives.
string answer; // Stores user's answer.
int count = 0; // Keeps track of the current question.
int score = 0; // Keeps track of user's score.
while (lives > 0 && count < 4) {
string question = questions[count]; // Gets current question from array.
// Modifying question if medium or hard difficulty selected.
if (level == 2) {
// Medium
question = modifyQuestion(question, 6);
}
else if (level == 3) {
// Hard
question = modifyQuestion(question, 2);
}
// Asking Question.
cout << "What is the capital city of " << question << endl; // Asks user the question.
getline(cin, answer); // Gets answer from user, includes answers that are more than one word.
answer[0] = toupper(answer[0]); // Converts first character to upper case.
int max = 0;
int max2 = 0;
if (answer == answers[count]) { // Checks user's answer against current answer.
cout << "Well Done! You've got one right" << endl; // Correct answer message.
count++; // Adds one to question counter.
score++; // Adds one to score.
correctAns[count] = answer;
max++;
}
else {
lives--; // Deducts one from lives.
cout << "Oops, Not quite right... You have " << lives << " lives remaining."; // Outputs incorrect message.
wrongAns[count] = answer;
max2++;
}
answersGiven(correctAns[0], wrongAns[0], max, max2);
}
if (lives == 0 && score == 0) { // Checks if user didnt get anything correct.
cout << "Wow.. 0 / 4. Thats not good." << endl;
}
else {
cout << "You got " << score << " Correct and had " << lives << " lives remaining" << endl;
}
cout << "\nThese are the questions you got wrong:\n";
}
string modifyQuestion(string q, int mod) {
for (int i = 0; i < q.length(); i++) {
if (i % mod == 0) { // If counter is divisible by the mod value.
q[i] = '*'; // Change current letter to an aterix.
}
}
return q; // return modified string back to the function.
}
string answersGiven(string correct[], string wrong[], int maxC, int maxW) {
for (int i = 0; i < maxC; i++) {
cout << correct[i] << " - Correct" << endl;
}
for (int i = 0; i < maxW; i++) {
cout << wrong[i] << " - Incorrect" << endl;
}
}

When I input a number in char type, why i can't get a whole number?

I input a number in char type variable. like 12 or 22. but, console show me a 1 or 2.
How i get a whole number 12 ,22 in console?
#include <iostream>
int main()
{
using namespace std;
char a = 0;
cin >> a;
cout << a << endl;
return 0;
}
Here is console result.
12
1
C:\Users\kdwyh\source\repos\MyFirstProject\Debug\MyFirstProject.exe(프로세스 18464개)이(가) 종료되었습니다(코드: 0개).
이 창을 닫으려면 아무 키나 누르세요...
The reason I don't use int, string and something is because I want to get both number and Character in one variable.
So I want to see the results of combined numbers and character at the same time.
in that process i can't get a whole number.
#include <iostream>
using namespace std;
int index = 0;
constexpr int pagenum = 10;
void chapterlist(void);
void nextlist(void);
void beforelist(void);
void movechapter(char a);
int main(void)
{
char userin = 0;
bool toggle = 0;
cout << "결과를 볼 챕터를 고르시오." << endl;
chapterlist();
cout << "다음 페이지로 이동: n" << endl;
cin >> userin;
if (userin == 'n')
{
backflash:
while(toggle == 0)
{
nextlist();
cin >> userin;
if (userin == 'b')
{
toggle = 1;
goto backflash;
}
else if (userin == 'n')
continue;
else
{
system("cls");
movechapter(userin);
break;
}
}
while(toggle == 1)
{
beforelist();
cin >> userin;
if (userin == 'n')
{
toggle = 0;
goto backflash;
}
else if (userin == 'b')
continue;
else
{
system("cls");
movechapter(userin);
break;
}
}
}
else
{
system("cls");
movechapter(userin);
}
return 0;
}
void chapterlist(void)
{
int x = 0;
for (x = index + 1; x <= index + 10; x++)
cout << "Chapter." << x << endl;
}
void nextlist(void)
{
system("cls");
cout << "결과를 볼 챕터를 고르시오." << endl;
index = index + pagenum;
chapterlist();
cout << "다음 페이지로 이동: n" << endl;
cout << "이전 페이지로 이동: b" << endl;
}
void beforelist(void)
{
system("cls");
cout << "결과를 볼 챕터를 고르시오." << endl;
index = index - pagenum;
chapterlist();
cout << "다음 페이지로 이동: n" << endl;
cout << "이전 페이지로 이동: b" << endl;
}
void movechapter(char a)
{
cout << "선택한 Chapter." << a << "의 결과입니다." << endl;
}
In movechapter(), console show me a is 1 or 2, not 12, 22.
First, you have to understand what achar type is.
Character types: They can represent a single character, such as 'A' or '$'. The most basic type is char, which is a one-byte character. Other types are also provided for wider characters.
To simplify that, char can only hold one character.
Where as with your code, "12" is actually 2 separate characters, '1' and '2', and that's the reason it would not work.
Instead of declaring a as a char type, you could declare it as an int type, which is a type designed to hold numbers. So you would have:
int a = 0;
However, do note that int often has a maximum value of 2^31.
Or you could use std::string to store character strings. However, do note that if you wish to do any calculations to your string type, you would need to convert them to a number type first:
int myInt = std::stoi(myString);
Edit:
So I have re-checked your code after your update, there is nothing wrong with using std::string in your case. You can still check if user have input n or b by:
if (userin == "n")
Note that you would use double quotation mark, or "letter", around the content that you want to check.
On the other hand, you could use:
if(std::all_of(userin .begin(), userin.end(), ::isdigit))
To check if user have input a number.
Although char is just a number, it's presumed to mean "single character" here for input. Fix this by asking for something else:
int a = 0;
You can always cast that to char as necessary, testing, of course, for overflow.
You should be reading characters into a string, and then converting that string into an int. It would also probably make more sense to use something like getline() to read input, rather than cin >> a.
#include <string>
#include <iostream>
#include <stdexcept>
#include <stdio.h>
int main() {
std::string input_string;
/* note that there is no function that will convert an int string
to a char, only to an int. You can cast this to a char if needed,
or bounds check like I do */
int value;
while(1) {
getline(std::cin, input_string);
/* std::stoi throws std::invalid_argument when given a string
that doesn't start with a number */
try {
value = std::stoi(input_string);
} catch (std::invalid_argument) {
printf("Invalid number!\n");
continue;
}
/* You wanted a char, the max value of a `char` is 255. If
you are happy for any value, this check can be removed */
if (value > 255) {
printf("Too big, input a number between 0-255\n");
continue;
}
break;
}
printf("Number is %hhu\n", value);
}

Sorting string array alphabetically in a 2D array (C++)

I have coded thus far and I am not sure how to sort using the 2-dimensional array. Basically, one function is for sorting an array of strings, another function is for swapping two strings. Any help would be appreciated. (Also I am not allowed to use c++ 11 :/)
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
void input_name(string&);
void sort_names(string&);
void repeat_pro(int&);
void sortArray(string, int);
int main() {
string b_list[100][2];
string name;
int choice;
int count=0;
cout << "Welcome to the Business Sorting Program!" << endl;
do{
input_name(name);
b_list[count][1] = name;
count++;
repeat_pro(choice);
cout<<"\n \n Your Businesses are:"<<endl;
for(int j=0; j<count; j++){
cout<<b_list[j][1]<<endl;
}
cout << "\n\n";
}while(choice == 0);
cout << "Thanks for using this program"<<endl;
return 0;
}
void input_name(string &name){
cout << "Enter in the name of the business: ";
getline(cin, name);
}
void sort_names(string &name){
}
void repeat_pro(int &choice){
cout << "Do you want to enter in more names: ";
string answ;
cin>>answ;
cin.ignore(1000,'\n');
if (answ == "YES" || answ == "Y" || answ == "yes" || answ == "y"){
choice = 0;
}
else {
choice = 1;
}
}
it is not clear to me from the description what problem the program really tried to solve. I'm assuming it's kind of like a two column spreadsheet, the second column is the name entered by the user(but what is in the first column?).
assume you need to keep the array in sorted order as the data goes in, just do a binary search (you can do a linear search for small dataset like 100 entries).
// we don't have lambda before C++11
struct comparator {
bool operator () (const string (&x)[2], const string (&y)[2]) const {
return x[1] < y[1];
}
};
//... omitted
string data[100][2];
int count = 0;
while (count < 100) {
// no rvalue, move, rvo, etc. before C++11
string name;
input_name(name);
// no type deduction and lambda
string (*position)[2] =
std::lower_bound(&data[0], &data[count], name, comparator());
int index = position - &data[0];
// simulate an vector::insert operation, but for our array
for (int i = count; i > index; --i) {
// before we had move in C++, we would do swap with an empty element.
// in this case, the entry at data[count] is default constructed
std::swap(data[i][1], data[i-1][1]);
}
data[index][1] = name;
}
//... omitted
of course we can use a typedef to make it cleaner, but that's left to you.

Creating 2 arrays of 2 structs.

I have been given a problem domain. To write a program which asks the user which fruits he wants to purchase and in how much quantity. Based on the input from the user, it produces a bill.
Example interaction:
Do you want to purchase fruit? Yes
Which fruit? Orange
How many pounds ? 2
Do you want to purchase another fruit? Yes
Which fruit? Apple
How many pounds? 1.5
Do you want to purchase anothe fruit? No
Thanks for your business.
Here is your bill:
Fruit Quantity Price per Lb Price
Orange 2 Lb 1.5 3
Apple 1.5 Lb 2 3
Total Amount 6
#include <iostream>
#include <string>
using namespace std;
struct fruitData
{
string fruitName;
float price;
};
struct invoiceData
{
char fruit_ordered;
float price1;
float quantity_ordered;
float totalFruitprice;
} ;
int main()
char choice;
string fruit_choice;
float pounds_choice;
int count=0;
fruitData fruits[5];
invoiceData customers[5];
strcpy(fruits[0].fruitName, "Banana");
strcpy(fruits[1].fruitName, "Apple");
strcpy(fruits[2].fruitName, "Pears");
strcpy(fruits[3].fruitName, "Oranges");
strcpy(fruits[4].fruitName, "Papaya");
fruits[0].price=1;
fruits[1].price=2;
fruits[2].price=2.5;
fruits[3].price=1.5;
fruits[5].price=1.40;
strcpy(customers[0].fruitName, "Banana");
strcpy(customers[1].fruitName, "Apple");
strcpy(customers[2].fruitName, "Pears");
strcpy(customers[3].fruitName, "Oranges");
strcpy(customers[4].fruitName, "Papaya");
customers[0].price=1;
customers[1].price=2;
customers[2].price=2.5;
customers[3].price=1.5;
customers[4].price=1.40;
cout << "Welcome to the fruit market" << endl;
cout << "Would you like to purchase fruit?" << endl;
cin >> choice >> endl;
while (choice == 'Y')
{
cout << "Which fruit?" << endl;
cin >> fruit_choice >> endl;
cout << "How many pounds?" << endl;
cin >> pounds_choice >> endl;
if (fruit_choice == "Banana")
{
customers[0].quantity_ordered = pounds_choice;
customers[0].total_price = customers[0].quantity_ordered * customers[0].price;
}
else if (fruit_choice == "Apple")
{
customers[1].quantity_ordered = pounds_choice;
customers[1].total_price = customers[1].quantity_ordered * customers[1].price;
}
else if (fruit_choice == "Pears")
{
customers[2].quantity_ordered = pounds_choice;
customers[2].total_price = customers[2].quantity_ordered * customers[2].price;
}
else if (fruit_choice == "Oranges")
{
customers[3].quantity_ordered = pounds_choice;
customers[3].total_price = customers[3].quantity_ordered * customers[3].price;
}
else (fruit_choice == "Papaya")
{
customers[4].quantity_ordered = pounds_choice;
customers[4].total_price = customers[4].quantity_ordered * customers[4].price;
}
}
for (count = 1 ; count <=5 ; count++)
{
if (customers[0].total_price != 0)
{
cout << customers[0].fruit_name <<
cout << customers[0].quantity_ordered <<
cout << customers[0].price <<
cout << customers[0].total_price <<
}
}
}
I am getting a lot of errors. One of them being the string in "string fruit_chioce" is not turning blue as it should. And the compiler says char choice should be preceded by a ";" . I am also having trouble associating an array for these structs. Any help would be appreciated , thank you.
The best way is to use std::vector. For example
#include <iostream>
#include <vector>
#include <string>
using namespace std;
struct Fruit {
string name;
float price;
};
int main() {
vector<Fruit> fruits;
while(true) {
Fruit fruit;
string answer;
cout << "Which fruit? ";
cin >> fruit.name;
cout << "How many pounds? ";
cin >> fruit.price;
fruits.push_back(fruit);
cout << "Do you want to purchase another fruit? ";
cin >> answer;
cout << endl;
if (answer=="No") break;
}
for(int i=0; i<(int)fruits.size(); ++i) {
cout << "Fruit " << i+1 << " -> Name: " << fruits[i].name << ", price: " << fruits[i].price << endl;
}
return 0;
}
After int main() there should be a { immediately following.
fruits is only 5 elements long, but you try to access the sixth here: (I guess it really should be 4 instead of 5)
fruits[5].price=1.40;
fruitName is a C++ string, you can't use strcpy with it (strcpy is for C strings, that is char*-based strings). Simply assign:
fruits[0].fruitName = "Banana";
Your while loop will never end, because you never ask again for input to choice.
Your last else here
else (fruit_choice == "Papaya")
should also be a else if.
Your for loop goes from zero to five (sixth element), but the array only has 5 elements, so it should be:
for (count = 1 ; count < 5 ; count++)
The last output lines should end with an operand (some variable to output) instead of <<. Also like every other statement they have to end with ;. For example with line break:
cout << customers[count].fruit_name << endl;
I also replaced 0 with count, because you surely don't want to always output the first array element.
In the strcuture fruitData
struct fruitData
{
string fruitName;
float price;
};
data member fruitName is defined as having type std::string. You may not use standard C function strcpy with objects of type std::string because they are not character arrays. You could use a simple assignment. For example
fruits[0].fruitName = "Banana";
But it would be better to initialize the array when it was defined. For example
fruitData fruits[5] =
{
{ "Banana", 1 }, { "Apple", 2 }, { "Pears", 2.5 },
{ "Oranges", 1.5 }, { "Papaya", 1.40 }
};
Also in structure invoiceData you defined data member fruit_ordered as
char fruit_ordered;
(a very strange decision) that is it can contain only one character. Moreover I think you meant fruitName instead of fruit_ordered because below you wrote
strcpy(customers[0].fruitName, "Banana");
but the structure does not declare this name. So again you may not use standard C function strcpy as you did because fruitName is not a character array.
Moreover you did not include header <cstring> where C functions are declared.
This statement (and similar statements)
cin >> choice >> endl;
is invalid. You may not use std::endl with std::cin
Also this loop
for (count = 1 ; count <=5 ; count++)
{
if (customers[0].total_price != 0)
{
cout << customers[0].fruit_name <<
cout << customers[0].quantity_ordered <<
cout << customers[0].price <<
cout << customers[0].total_price <<
}
}
has no any sense.
I think there are other errors but it is enogh what i already showed. Take into account that valid range of indexes for an array having 5 elements is 0 - 4
In this code
fruits[0].price=1;
fruits[1].price=2;
fruits[2].price=2.5;
fruits[3].price=1.5;
fruits[5].price=1.40;
you have a typo. Here the indexes are 0, 1, 2, 3, 5 but must be 0, 1, 2, 3, 4.
Shortly speaking the code is full of errors.

I'm getting a weird error for a program that seems like it should "just work."

I present to you all a program I'm working on for my college programming course. I still have a little ways to go before it completely meets my assignment's requirements, but I've gotten a basic draft of the program error-free (supposedly) and it appears to run… but then it suddenly kicks me into Xcode's debugger and gives me:
Thread 1: EXC_BAD_ACCESS(code=2, address=0x7fff95c1e5f5)
Here's the command line output, up until it kicks me out:
-----------------------
Quarterly_sales_taxator
-----------------------
How many company divisions will we be dealing with? 2
Am I correct in assuming that there are 4 sales quarters? yes
Please enter the sales Company Division #1 brought in for Sales Quarter #1 20
(lldb)
Here's my code:
//
// quarterly_sales_taxator.cpp
// Ch. 7 program #7
//
// Created by John Doe on 11/27/12.
//
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <cctype>
using namespace std;
void read_company_divisions_and_sales_quarters(double **, int, int);
//void write_company_divisions_and_sales_quarters_to_array(double **, int, int); // This will be used later on to read data from a file.
void display_quarterly_sales_array(double **, int, int);
string temp; // A global temporary placeholder variable; I use this several times.
int main()
{
int COMPANY_DIVISIONS,
SALES_QUARTERS = 4;
double **quarterly_sales_form;
cout << "\n\n-----------------------\nQuarterly_sales_taxator\n-----------------------\n\n";
cout << "\nHow many company divisions will we be dealing with? ";
getline(cin, temp);
stringstream(temp)>>COMPANY_DIVISIONS;
while (COMPANY_DIVISIONS < 1 || isdigit(COMPANY_DIVISIONS == false))
{
cout << "\n\n------"
<< "\nError:"
<< "\n------"
<< "\n\nYou have entered an invalid choice."
<< "\nPlease type a number greater than zero. ";
getline(cin, temp);
stringstream(temp)>>COMPANY_DIVISIONS;
}
cout << "\n\nAm I correct in assuming that there are 4 sales quarters? ";
getline(cin, temp);
// Convert to uppercase.
for (int count = 0; count < temp.length(); count ++)
{
temp[count] = toupper(temp[count]);
}
if (temp == "NO" || temp == "NOPE" || temp == "INCORRECT" || temp == "YOU ARE NOT" || temp == "YOU ARE INCORRECT" || temp == "NEGATIVE" || temp == "NEGATORY")
{
cout << "\nOk, then how many sales quarters are we dealing with? ";
getline(cin, temp);
stringstream(temp)>>SALES_QUARTERS;
}
cout << endl << endl;
// This sets up the 2d array.
quarterly_sales_form = new double *[COMPANY_DIVISIONS];
for (int count = 0; count < COMPANY_DIVISIONS; count ++)
{ quarterly_sales_form[COMPANY_DIVISIONS] = new double [SALES_QUARTERS]; }
read_company_divisions_and_sales_quarters(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS);
// write_company_divisions_and_sales_quarters_to_array(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS); // I'll add this feature later.
cout << "\n\nHere's what you entered:\n\n";
display_quarterly_sales_array(quarterly_sales_form, COMPANY_DIVISIONS, SALES_QUARTERS);
// Since we used a series of pointers, we need to free the allocated space back up.
for (int count = 0; count < COMPANY_DIVISIONS; count ++)
{ delete[] quarterly_sales_form[COMPANY_DIVISIONS]; }
delete[] quarterly_sales_form;
return 0;
}
/*############################################
# read_company_divisions_and_sales_quarters #
############################################*/
void read_company_divisions_and_sales_quarters(double **array, int DIVISIONS, int QUARTERS)
{
for (int count = 0; count < QUARTERS; count++)
{
for (int index = 0; index < DIVISIONS; index++)
{
cout << "\nPlease enter the sales Company Division #" << count+1 << " brought in for Sales Quarter #" << index+1 << " ";
getline(cin, temp);
stringstream(temp) >> array[count][index];
}
}
}
/*################################
# display_quarterly_sales_array #
#################################*/
void display_quarterly_sales_array(double **array, int DIVISIONS, int QUARTERS)
{
for (int count = 0; count < DIVISIONS; count++)
{
cout << "\nCompany division #" << count+1 << ":\n";
for (int index = 0; index < QUARTERS; index++)
{ cout << array[count][index] << ", "; }
}
}
Can some kind soul please tell me what I'm doing wrong?
{ quarterly_sales_form[COMPANY_DIVISIONS] = new double [SALES_QUARTERS]; }
In this line, COMPANY_DIVISIONS should be count.
In addition to what Dan Hulme said, it seems this line
stringstream(temp) >> array[count][index];
should really be
std::istringstream(temp) >> std::skipws >> array[index][count];
In addition to using std::istringstream rather than std::stringstream and making sure that an lvalue is at hand, which isn't strictly needed until the type read becomes more interesting, this also reverses the indices: index runs over COMPANY_DIVISIONS and count over SALES_QUARTERS.
The real question is, of course: Who hands out assignments like this? Pointer manipulations and allocations are best left to low-level library writers. This is C++ not C: we can and should use abstractions. Getting this code exception safe is a major challenge and there is no point in teaching people how to write broken (e.g. exception unsafe) code.