Printing elements in a string list by index C++ - c++

Hi here is what I have so far. The operation printList(strList,indexList) will print the elements in strList that are in positions specified by indexList but im having trouble doing so. I'm trying to use the public STL container operations but having trouble. Any help would be great! Thank you!
#include<cstdlib>
#include<iostream>
#include<string>
#include<list>
using namespace std;
// PURPOSE: To have the user enter strings into list 'strList'. No return value.
void enterStringList(list<string>&strList){
while (true){
string entry;
cout << "Please enter a string or just press 'enter' to quit: ";
getline(cin, entry);
if (entry.empty())
break;
strList.push_back(entry);
}
}
void enterIntegerList(list<int>& intList, int limit) {
bool shouldContinue = true;
while (shouldContinue)
{
int number;
do
{
string entry;
cout << "Please enter an integer [0-"
<< limit
<< "], or just press 'enter' to quit: ";
getline(cin, entry);
if (entry.empty())
{
shouldContinue = false;
break;
}
number = atoi(entry.c_str());
} while ((number < 0) || (number > limit));
if (shouldContinue)
intList.push_back(number);
}
}
// PURPOSE: To print the elements in L that are in positions specified by P.
// No return value.
void printList(list<string>& strList, list<int>& indexList){
// HERE }
int main() {
list<string> strList;
list<int> indexList;
enterStringList(strList);
if (!strList.empty())
{
enterIntegerList(indexList, strList.size() - 1);
indexList.sort();
printList(strList, indexList);
}
return(EXIT_SUCCESS);}

Related

Whats a good way to get the program to end based on user input?

I did my "Hello World", I'm just getting started on my programming adventure with C++. Here is the first thing I've written, what are some ways to get it to end with user input? I'd like a yes or no option that would terminate the program. Also any feedback is welcome, thank you
#include <iostream>
using namespace std;
void Welcome();
void calculateNum();
void tryAgain();
int main() {
Welcome();
while (true) {
calculateNum();
tryAgain();
}
system("pause");
}
void calculateNum() {
float userNumber;
cin >> userNumber;
for (int i = 100; i >= 1; i--) {
float cNumber = i* userNumber;
cout << i << " >>>>> " << cNumber << endl;
}
}
void Welcome() {
cout << "Welcome \n Enter a number to see the first 100 multiples \n";
}
void tryAgain() {
cout << "Try again? Enter another number... ";
}
Here is one option:
Switch to do ... while loop, with the condition at the end.
Make your tryAgain() function return a boolean and put it in the while condition.
In tryAgain function read input from the user, and compare it to expected answers.
First, lets add a new header for string, it will make some things easier:
#include <string>
Second, lets rebuild the loop:
do {
calculateNum();
} while (tryAgain());
And finally, lets modify the function:
bool tryAgain() {
string answer;
cout << "Try again? (yes / no)\n";
cin >> answer;
if (answer == "yes") return true;
return false;
}
Now, there is a slightly shorter way to write that return, but it might be confusing for new learners:
return answer == "yes";
You don't need the if because == is an operator that returns bool type value.
You can change your calculateNum() in the following way:
Change the return value of your calculateNum() function into bool to indicate whether the program shall continue or stop
read the input into a std::string
check if the string is equal to your exit string like 'q' for quit
3.a in that case, your function returns false to indicate the caller that the program shall stop
3.b otherwise, create a stringstream with your string and read the content of the stream into your float variable and continue as you do like now
In your loop in your main function you break if calculateNum() returned false
Here is a simple solution:
#include <iostream>
// Here are two new Includes!
#include <sstream>
#include <string>
using namespace std;
void Welcome();
// Change return value of calculateNum()
bool calculateNum();
void tryAgain();
int main()
{
Welcome();
while (true)
{
if (!calculateNum())
break;
tryAgain();
}
system("pause");
}
bool calculateNum()
{
//Read input into string
string userInput;
cin >> userInput;
//Check for quit - string - here just simple q
if (userInput == "q")
return false;
//otherwise use a std::stringstream to read the string into a float as done before from cin.
float userNumber;
stringstream ss(userInput);
ss >> userNumber;
//and proces your numbers as before
for (int i = 100; i >= 1; i--)
{
float cNumber = i * userNumber;
cout << i << " >>>>> " << cNumber << endl;
}
return true;
}
void Welcome()
{
cout << "Welcome \n Enter a number to see the first 100 multiples \n";
}
void tryAgain()
{
cout << "Try again? Enter another number... ";
}
Having your users input in a string you can even do further checks like checking if the user entered a valid number, interpret localized numbers like . and , for decimal delimitters depending on your system settings and so on.

Parallel Arrays in 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;
}

Queue using struct (Taxi dispatch problem)

I want to write program that reads command from user, when d is entered a taxi is entered ,it prompts to enter driver_id and stores taxi in in queue (queue can have maximum n taxi), when command c is entered by customer it assigns the earliest taxi in the queue to the customer.
I'm trying to solve it using struct member function so that our code looks good, but although I have initialized n=4, it is only able to store 2 taxi, and shows me that the queue is full for the 3rd entry, which should not happen. Please review my approach.
Program run as such:
PS C:\Users; if ($?) { g++struct_taxi};; if ($?) { .\struct_taxi}
enter command:d
enter driverid:122
enter command:d
enter driverid:124
enter command:d
enter driverid:126
Q is full
Code:
#include<iostream>
using namespace std;
const int n=4;
struct Queue{
int elements[n],nwaiting,front;
void initialize(){
nwaiting=0;
front=0;
}
bool insert(int v){
if(nwaiting>=n)
return false;
elements[(front+nwaiting)%n]=v;
nwaiting++;
return true;
}
bool remove(int &v){
if(nwaiting==0)
return false;
else{
v=elements[front];
front=(front+1)%n;
nwaiting--;
return true;
}
}
};
int main(){
Queue q;
q.initialize();
while(true){
cout<<"enter command:";
char c;cin>>c;
if(c=='d'){
cout<<"enter driverid:";
int driverid;cin>>driverid;
if(!q.insert(driverid)){
cout<<"Q is full\n";}
else{
q.insert(driverid);
}
}
else if(c=='c'){
int driverid;
if(!q.remove(driverid)){
cout<<"No taxi available.\n";
}
else
//q.remove(driverid);
cout<<"assigning:"<<" "<<driverid<<endl;
}
}
}
The problem is that when you check the condition if(!q.insert(driverid)), you've already insert that driver into the system. Then the else statement insert it another time with q.insert(driverid);
So the solution is to simply remove the else statement.
#include<iostream>
using namespace std;
const int n=4;
struct Queue
{
int elements[n],nwaiting,front;
void initialize()
{
nwaiting=0;
front=0;
}
bool insert(int v)
{
if(nwaiting>=n) {return false;}
elements[(front+nwaiting)%n]=v;
nwaiting++;
return true;
}
bool remove(int &v)
{
if(nwaiting==0)
return false;
else
{
v=elements[front];
front=(front+1)%n;
nwaiting--;
return true;
}
}
};
int main()
{
Queue q;
q.initialize();
while(true)
{
cout<<"enter command:";
char c;
cin>>c;
if(c=='d')
{
cout<<"enter driverid:";
int driverid;
cin>>driverid;
if(!q.insert(driverid))
{
cout<<"Q is full\n";
}
}
else if(c=='c')
{
int driverid;
if(!q.remove(driverid))
{
cout<<"No taxi available.\n";
}
else {cout<<"assigning:"<<" "<<driverid<<endl;}
}
}
}
Result:
enter command:d
enter driverid:121
enter command:d
enter driverid:122
enter command:d
enter driverid:123
enter command:d
enter driverid:124
enter command:d
enter driverid:125
Q is full
An easier way obviously is to use std::queue, a data structure used for situation exactly like this, and as it came with the same functionality of your Queue struct, the code would be much shorter:
#include <iostream>
#include <queue>
using namespace std;
const int maxn=2;
int main()
{ queue<int> q;
while(true)
{
cout << "Enter command : "; char c; cin >> c;
if (c == 'd') //if inserting new driver
{
cout << "Enter driver's ID : "; int id; cin >> id; //input id
if (q.size() == maxn) {cout << "Queue is full\n";} //if size of queue is equal to maxn, no insert
else {q.push(id);} //else insert
}
else if (c == 'c')
{
if (q.empty()) {cout << "No driver available\n";} //if no driver, no assigning
else
{
int curDriver = q.front(); //take drive in front of queue
q.pop(); //take the driver id out of queue
cout << "Assigned driver : " << curDriver << "\n";
}
}
}
}
Result:
Enter command : d
Enter driver's ID : 123
Enter command : d
Enter driver's ID : 124
Enter command : d
Enter driver's ID : 125
Queue is full
Enter command : c
Assigned driver : 123
Enter command : c
Assigned driver : 124
Enter command : c
No driver available
Enter command :
Also, it's not recommended to use keywords like front, remove, etc... for variable names. And check out Why is "using namespace std;" considered bad practice?

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.

Detect real numbers beyond whole numbers

This code is meant to detect REAL numbers from a string entered continuously by a user, and return the found real number as a double value . I was able to construct it to the point where it detects whole numbers, but if I try a decimal number it doesn't detect it. I think my error is within my isvalidReal() function, but I'm not sure how to move things around to get it to work.
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
double getaReal(); //function prototype
int value;
cout << "Enter a number: ";
value = getaReal();
cout << "the number entered is a real number: " <<value << endl;
return 0;
}
bool isvalidReal(string str) //function to find real numbers.
{
int start = 0;
int i;
bool valid = true;
bool sign = false;
if (int(str.length()) == 0) valid = false; //check for empty string
if (str.at(0) == '-' || str.at(0) == '+') //check for sign
{
sign = true;
start = 1; //check for real num at position 1
}
if (sign && int(str.length()) == 1) valid = false; //make sure there's atleast 1 char after the sign
i = start;
while (valid && i<int(str.length()))
{
if (!isdigit(str.at(i))) valid = false; //found a non-digit character
i++; // move to next character
}
return valid;
}
double getaReal()
{
bool isvalidReal(string); //function declaration prototype
bool isnotreal = true;
string input;
while (isnotreal)
{
try
{
cin >> input; //accepts user input
if (!isvalidReal(input)) throw input;
}
catch (string e)
{
cout << "No real number has been detected, continue to\n enter string values: ";
continue; //continues user input
}
isnotreal = false;
}
return atof(input.c_str());
}