How can I add numbers before my output here? - c++

I'm working on a C++ program for my class and I'm unsure about a specification. I want to add numbers before the output of string orderCode but am unsure how to do this. For example, output for the input "BF12" would be "12 Black Forest cakes." I am trying to include the number and amount of cakes into one single string variable. Could anyone offer me some pointers? Anything would be very much appreciated.
Here is my code:
#include <iostream>
using namespace std;
int main() {
string orderCode;
string repeat = "y";
while ("y" == repeat) {
cout << "\nWelcome to the Great Cake company!\n";
cout << "\nEnter the cake order code: ";
cin >> orderCode;
int quantity = orderCode.length() - 1;
if (orderCode == "BF2")
{ (cout << orderCode.substr(quantity) << " Black Forest cakes");
}
if (orderCode == "CC")
{ (cout << "Carrot cakes");
}
if (orderCode == "CM")
{ (cout << "Chocolate Mint cakes");
}
if (orderCode == "DF")
{ (cout << "Devil's Food cakes");
}
if (orderCode == "GC")
{ (cout << "German Chocolate cakes");
}
if (orderCode == "PC")
{ (cout << "Pumpkin Cheesecakes");
}
if (orderCode == "RC")
{ (cout << "Rum cakes");
}
if (orderCode == "T")
{ (cout << "Tiramisu cakes");
}
cout << "\nOrder more? (y/n) ";
cin >> repeat;
}
return 0;
}

You want to parse the user input, assuming the digit will always be after the letters and assuming the digit is a decimal (thus not counting ABCDEF as part of the digit).
string orderCode = "BF12";
size_t last_index = orderCode.find_last_not_of("0123456789");
string result = orderCode.substr(last_index + 1);
result += " Black Forest cakes";
cout << result << endl;
Meanwhile for your switch case you still need to erase the digit part of the input.
orderCode.erase(last_index+1);
You can then compare to orderCode

You need to omit BF and exctract the number. Since BF has length of 2, you need to print the rest:
cout << orderCode.substr(2, quantity) << " Black Forest cakes"
Meanwhile, your switch case does not make any sense.

Related

To confirm only 1 and 0 exist in the Binary

I wanted to use only 1 and 0 for the binary. But instead the answer keep giving me the 2nd option with whatever number I typed. I had tried where did I programmed wrongly but unfortunately I still can't find it. So I hoped that I could get some help here.
#include<iostream>
#include<cmath>
using namespace std;
int DualzahlZuDezimal(long long n)
{
int dez = 0;
int i = 0, rem;
while (n != 0)
{
rem = n % 10;
n /= 10;
dez += rem * pow(2, i);
++i;
}
return dez;
}
string a;
int main()
{
long long n;
int dez;
cout << "Test Ein- und Ausgabe : \n";
cout << "----------------------- \n";
cout << "Eingabe einer Dualzahl : ";
cin >> n;
if ((n == '1') && (n == '0'))
{
cout << "Dual : " << n << endl;
cout << "Dezimal : " << DualzahlZuDezimal(n) << endl;
cout << "cin ok ? : ja-ok" << endl;
return 0;
}
else
{
cout << "Dual : 0" << endl;
cout << "Dezimal : 0" << endl;
cout << "cin ok ? : nein-nicht ok" << endl;
return 0;
}
}
If I understand this right, you want the user to enter a binary number, like 10001101001, and you will show the decimal equivalent (1129 in this case).
There are 2 general ways to do that yourself:
You can read the value as a number, as you do, and then apply your conversion
process, except that you check that rem is either 0 (in which case you do
nothing), or 1 (in which case you add the power of 2). If it's another value,
you report the error, and return 0.
You can read the value as a std::string instead. Then you can use
std::find_first_not_of()
to check for contents other than 0 or 1:
if (n.find_first_not_of("01") != string::npos) { /* complain */ }
but then you need to do the conversion based on characters.
But the best approach is not to reinvent the wheel and instead let the standard library handle it for you via stol():
#include <cstddef>
#include <iostream>
#include <string>
using namespace std;
int
main()
{
string text;
cout << "Enter a binary number: " << flush;
cin >> text;
size_t endpos = 0;
long decimal_number = stol(text, &endpos, 2); // base 2 == binary
if (endpos != text.size()) {
cerr << "'" << text << "' is not a valid binary number!" << endl;
return 1;
}
else {
cerr << "binary number: " << text << endl;
cerr << "decimal number: " << decimal_number << endl;
return 0;
}
}
Keep in mind that input from the console is text. If you need to check that the text matches a particular format (in this case, consists entirely of 1's and 0's), the simplest approach is to look at that text:
std::string input;
std::cin >> input;
bool input_is_valid = true;
for (int i = 0; input_is_valid && i < input.length(); ++i) {
if (input[i] != '0' && input[i] != '1')
input_is_valid = false;
}
then, if the input is valid, convert the text to a numeric value:
long long n = std::stoll(input);

Generate Random Letters Depending on User Input

I have to make a simple letter guessing game. So far I've finished almost everything but I'm not sure about what to do when it comes to one task.
So before the game begins it asks the user to input two things:
Enter the amount of different characters: (if 4 is entered for example, the letters chosen would be from A to the 4th letter, A-D only)
and
Enter the pattern length:
The pattern length input is working fine, but I'm having a tough time figuring out how to modify the generate code function to add the amount of different characters.
Any tips?
#include <iostream>
#include <random>
#include <string>
using namespace std;
size_t len;
string str;
void generate_code()
{
str.string::reserve(len);
random_device rd;
mt19937 gen{rd()};
uniform_int_distribution<char> dis{'A', 'Z'};
for (size_t i = 0; i < len; i++)
{
str += dis(gen);
}
}
void guess_checker()
{
string guess{};
size_t trial_count = 0, match_count = 0;
do
{
cout << "Enter your guess: " << endl;
cin >> guess;
if (guess.size() != len)
{
cout << "error: invalid guess" << endl;
}
else
{
match_count = 0;
for (size_t i = 0; i < len; i++)
{
if (guess[i] == str[i])
++match_count;
}
cout << "You guessed " << match_count << " character"
<< (match_count == 1 ? "" : "s") << " correctly." << endl;
}
++trial_count;
}
while (match_count != len);
cout << "You guessed the pattern in " << trial_count << " guess"
<< (trial_count == 1 ? "" : "es") << "." << endl;
}
int main()
{
int amount;
cout << "Enter the amount of different characters: ";
cin >> amount;
cout << "Enter the pattern length: ";
cin >> len;
generate_code();
guess_checker();
return 0;
}
Simply change your generator line to:
uniform_int_distribution<char> dis{'A', 'A' + amount - 1};
I would also recommend adding some validation beforehand, such as:
if (amount < 1 || amount > 26) {
cout << "Bad amount" << endl;
// exit or something
}

Extending my array

From what I am reading from the book and from prior examples that I have been doing from the book this is what I have come up with. I appreciate the extra advice but I am trying to learn what the chapter is trying to show me so I can move on and learn the basics before I try code I have never seen before. I want the user to type 0 to end the loop but for some reason the loop keeps going? I think I may be missing something that is preventing it from stopping.
// Ex4_08.cpp
// Initializing pointers with strings
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main()
{
bool keepgoing = true;
int answer;
while (keepgoing = true)
{
const char* pstr[]{ "Aa", // Initializing a pointer array
"Bb",
"Cc",
"Dd",
"Ee",
"Ff",
"Gg",
"Hh",
"Ii",
"Jj",
"Kk",
"Ll",
"Mm",
"Oo",
"Pp",
"Qq",
"Rr",
"Ss",
"Tt",
"Uu",
"Vv",
"Ww",
"Ss",
"Yy",
"Zz",
};
const char* pstart{ "Your letter is " };
int dice{};
cout << endl
<< "Enter a number between 1 and 26 " << _countof(pstr) << ": ";
cin >> dice;
cout << endl;
if (dice >= 1 && dice <= _countof(pstr)) // Check input validity
cout << pstart << pstr[dice - 1]; // Output star name
else
cout << "Sorry, you haven't selected a correct number."; // Invalid input
cout << "Do you want to do this again? Type 0 for no: " << endl;
cin >> answer;
if (answer == 0)
{
keepgoing = false;
}
}
cout << endl;
return 0;
}
I've modified you initial code sample, using vector and string which are more C++ and easier to use:
#include <iostream>
#include <string> // for string
#include <vector> // for vector
using std::cin;
using std::cout;
using std::endl;
int main()
{
std::vector<std::string> pstr;
for (char c = 'a'; c <= 'z'; c++) // cycle over the 26 ASCII letters
{
std::string temp; //
temp += c - 32; // add capital character (e.g A)
temp += c; // add character (e.g. a)
pstr.push_back(temp); // push the new string (e.g. Aa) to the vector
}
const char* pstart{ "Your letter is " };
int dice{};
while (true)
{
cout << endl
<< "Enter a number between 1 and 26 " << pstr.size() << ": ";
cin >> dice;
if (dice == 0)
{
break; //break if the user enters 0
}
cout << endl;
if (dice >= 1 && dice <= pstr.size()) // Check input validity
cout << pstart << pstr[dice - 1]; // Output star name
else
cout << "Sorry, you haven't selected a correct number."; // Invalid input
}
cout << endl;
return 0;
}
Your code is wrong here:
while (keepgoing = true) {
...
if (answer == 0) {
keepgoing = false;
}
}
You are setting the keepgoing to false, but in the while condition you are resenting it to true. You must use the == operator (as in while(keepgoing == true)) or remove it (while(keepgoing)).
Otherwise, you may use while(true) or for (;;) and break instead of keepgoing = false:
for (;;) { // or while (true); to me, that's only a matter of preference.
...
if (answer == 0) {
break; // exit the loop
}
}
They do produce infinite loop until you enter the break condition.
Change this line:
while (keepgoing = true)
To this:
while (keepgoing == true)
The first assigns the value true to the variable keepgoing. The second checks of the value of keepgoing is true. This is a very common issue that trips of many new programmers (and occasionally an old one). :-)

Troubleshooting my c++ programs

I've got these 2 programs for the current chapter in my C++ class that I cant seem to get to work and I dont understand why.
The first project requests
"Create a program that displays the appropriate shipping charge based on the zip code entered by the user. To be valid, the zip code must contain exactly five digits and the first three digits must be either “605” or “606”. The shipping charge for “605” zip codes is $25. The shipping charge for “606” zip codes is $30. Display an appropriate error message if the zip code entered is invalid. Use the sentinel value “X” to end the program."
#include <iostream>
#include <string>
using namespace std;
string zipCode = "";
string zip = "";
int main() {
cout << "ENTER AN X TO STOP ZIP CODE DATA ENTRY." << endl << endl;
cout << "Enter Zip Code: ";
getline(cin, zipCode);
while (zipCode != "x")
{
if (zipCode.length() == 5)
{
if (zipCode.find("605", 0))
{
cout << "Shipping charge is $25" << endl;
}
else if (zipCode.find("606", 0))
{
cout << "Shipping charge is $30" << endl;
}
else
cout << "Invalid Zip Code.";
}
else
{
cout << "Zip code must contain exactly 5 digits." << endl;
}
cout << "Enter Zip Code: ";
getline(cin, zipCode);
}
cout << endl << "End of Program.";
return 0;
}
I tried a similar structure for the second program and cant get it to work properly either.
Create a program that displays the color of the item whose number is entered by the user. All item numbers contain exactly seven characters. All items are available in four colors: blue, green, red, and white. The fourth character in the item number indicates the item number, as follows: a B or b indicates Blue, a G or g indicates Green, a R or r indicates Red, and a W or w indicates White. If the item number is not exactly seven characters display the appropriate error message. If the fourth character is not one of the valid color characters, display the appropriate error message. Use the sentinel value “X” to end the program.
#include <iostream>
#include <string>
using namespace std;
string itemCode = "";
int main() {
cout << "ENTER AN X TO STOP ITEM NUMBER DATA ENTRY." << endl << endl;
cout << "Enter Item Number: ";
getline(cin, itemCode);
while (itemCode != "x")
{
if (itemCode.length() == 7)
{
if (itemCode.find("B", 3) == "B")
{
cout << "Color is blue." << endl;
}
else if (itemCode.find("G", 3) == "G")
{
cout << "Color is green." << endl;
}
else if (itemCode.find("R", 3) == "R")
{
cout << "Color is Red." << endl;
}
else if (itemCode.find("W", 3) == "W")
{
cout << "Color is White." << endl;
}
else
cout << "Invalid color code found in item number.";
}
else
{
cout << "Item number must contain exactly 7 characters." << endl;
}
cout << "Enter Item Number: ";
getline(cin, itemCode);
}
cout << endl << "End of Program.";
return 0;
}
From glancing at your code, two obvious problems come to mind that's likely the source of your issues:
You're not checking if getline successfully grabbed the input.
Your usage of string::find's return value is wrong. You need to check for std::npos to see if there's a match or not. See here if you need more details.
For your first problem, you want something like:
while (getline(cin, zipCode) && zipCode != "x")
// ...
And removing the other getlines.
For the second, your usage should look something like:
if (zipCode.find("605", 0) != string::npos)
// ...
Your current if (zipCode.find("605", 0)) does not work because anything other than 0 or false is considered truthy. std::string::npos is typically defined as -1 which means the expression is true if the zipCode isn't found -- the opposite of your desired behavior.

When using fstream in C++, how can I filter out control and formatting characters?

I have one of those basic assignments where you need to count the numbers of specific types of characters in an input file. There are 3 files involved, the main program (which I will include below), the hopper.txt input text to be analyzed, and the sample output.txt which demonstrates what the output should look like in the command line.
I believe I have everything set but my final numbers arnt turning out correctly. Specifically, my other and total counters are about 200 over. Now I've done some counting with other programs and am pretty sure that the sample output is correct which is why I suspect that I must be counting the hidden characters (and they must be there because the output isn't just a block of text).
I've tried casting each character to an int in order to see what its ascii value is and go off of that range but my IDE (Xcode) says that "comparison of constant with expression of type 'bool' is always true", and the check doesn't seem to catch anything.
Here are the other two files:
hopper.txt
sample output.txt
/***************************************************************
CSCI 240 Program 4 Summer 2013
Programmer:
Date Due: 7/14/14
Purpose: This program reads in the characters from a text file.
While reading them it takes cultivates relivant data about
the frequency of different ascii characters and shares its
results.
***************************************************************/
#include <iostream>
#include <iomanip>
#include <fstream>
#include <unistd.h>
#define FILENAME "/Users/username/Documents/NIU/240/Assigntment\ 4/hopper.txt"
using namespace std;
bool isVowel(char ch);
bool isConsonant(char ch);
int main()
{
ifstream inFile;
inFile.open (FILENAME, ios::in);
char ch;
int t_total = 0;
int t_vowel = 0;
int t_consonant = 0;
int t_letter = 0;
int t_leftParen = 0;
int t_rightParen = 0;
int t_singleQuote = 0;
int t_doubleQuote = 0;
int t_digit = 0;
int t_other = 0;
//See if we successfully imported the file
if (inFile.fail())
{
cout<< "\nThe file entitled: " << FILENAME << " failed to open.\n";
return 0;
}
do
{
//get next letter and print it out
inFile.get (ch);
cout << ch;
//increment total
t_total++;
//check if the character is a letter and if so if it is a vowel or consonant
if(isalpha(ch)){
t_letter++;
//we have found a letter
if(isVowel(ch)) {
t_vowel++;
//we have found a vowel
}
else if(isConsonant(ch)) {
t_consonant++;
//we have found a consonant;
}
else {
cout << "\nYou shouldnt be here...";
}
}
//check if the character is a digit
else if (isdigit(ch)) {
t_digit++;
//we have found a digit
}
//filter out formating characters
else if (!( 32 <= ((int)ch) <= 255)) {
continue;
}
//covers all other cases of askii characters
else {
switch(ch) {
case '(':
t_leftParen++;
break;
case ')':
t_rightParen++;
break;
case '\'':
t_singleQuote++;
break;
case '\"':
t_doubleQuote++;
break;
default:
t_other++;
break;
}
}
} while (inFile);
//These are really just here for the convience of not changing each value while working on formatting
int width1 = 25;
int width2 = 6;
//print out the totals found in the document
cout << "\n\nSummary\n";
cout << fixed << setw(width1) << "\nTotal characters:" << setw(width2) << right << t_total;
cout << fixed << setw(width1) << "\nVowels:" << setw(width2) << right << t_vowel;
cout << fixed << setw(width1) << "\nConsonants:" << setw(width2) << right << t_consonant;
cout << fixed << setw(width1) << "\nLetters:" << setw(width2) << right << t_letter;
cout << fixed << setw(width1) << "\nDigits:" << setw(width2) << right << t_digit;
cout << fixed << setw(width1) << "\nLeft parentheses:" << setw(width2) << right << t_leftParen;
cout << fixed << setw(width1) << "\nRight parentheses:" << setw(width2) << right << t_rightParen;
cout << fixed << setw(width1) << "\nSingle quotes:" << setw(width2) << right << t_singleQuote;
cout << fixed << setw(width1) << "\nDouble quotes:" << setw(width2) << right << t_doubleQuote;
cout << fixed << setw(width1) << "\nOther:" << setw(width2) << right << t_other;
return 0;
}
/***************************************************************
Function: isVowel
Use: Checks if the inputed character is a vowel.
Arguements: 1. ch: A askii character
Returns: true if it is a vowel, false if it is not
***************************************************************/
bool isVowel(char ch) {
//double check we have a letter
if(isalpha(ch)) {
//reduce to lower case to reduce the number of cases that must be checked
ch = tolower(ch);
if(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {
return true;
}
else {
return false;
}
}
return false;
}
/***************************************************************
Function: isConsonant
Use: Checks if the inputed character is a consonant.
Arguements: 1. ch: A askii character
Returns: true if it is a consonant, false if it is not
***************************************************************/
bool isConsonant(char ch) {
//So long as it is a letter, anything that is not a vowel must be a consonant
if(isalpha(ch)) {
return !isVowel(ch);
}
return false;
}
You can use std::isspace to test if a character is one of :
space (0x20, ' ')
form feed (0x0c, '\f')
line feed (0x0a, '\n')
carriage return (0x0d, '\r')
horizontal tab (0x09, '\t')
vertical tab (0x0b, '\v')
And ignore those by adding a test in your reading loop :
else if (std::isspace(ch)) {
continue; // Do not update counters
}