My program doesn't quite work right - c++

#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
string numString(int k)
{
string str;
switch (k) {
case 0 : str ="ZERO"; break;
case 1 : str ="ONE"; break;
case 2 : str ="TWO"; break;
case 3 : str ="THREE"; break;
case 4 : str ="FOUR"; break;
case 5 : str ="FIVE"; break;
case 6 : str ="SIX"; break;
case 7 : str ="SEVEN"; break;
case 8 : str ="EIGHT"; break;
case 9 : str ="NINE"; break;
}
return str;
}
int main(int argc, char** argv) {
int value;
int digit;
cout << "Enter a number: ";
cin >> value;
while (value > 0 )
{
digit = value % 10;
value = value / 10;
cout << numString(value) << endl;
}
return 0;
}
My program is supposed to prompt the user for an integer value read that value, and output the word equivalent of each digit
For example if "9502" was entered it would output "NINE FIVE ZERO TWO"
Yet mine only outputs "NINE ZERO" and then stops. I can't figure out what I'm doing wrong, any help at all is greatly appreciated.

Yet mine only outputs "NINE ZERO" and then stops.
That's literally what you told it to do!
while (value > 0 )
You'll have to find some other way to signal a "termination" condition if zero is supposed to be valid.
Traditionally we let the system's own end-of-file signalling take care of that for us, so that we don't have to "reserve" some otherwise-valid input and use it as a signal flag.
while (cin >> value) {
digit = value % 10;
value = value / 10;
cout << numString(value) << endl;
}
That fixes your loop, although unfortunately your maths are still wrong and your output is not what you intend. In fact, your digit variable is not used at all. I am not going to spoonfeed an algorithm here: you'll have to work out on paper how to achieve the business logic. :)

This is an analysis of your program using the input 9502.
Iteration 1, in main:
(new) value = 9502 / 10;
(new) digit = 9502 % 10;
value == 950;
digit == 2;
call numString(950);
// Note: there is no case for 950 in numString so an empty string is returned.
Iteration 2, in main:
(new) value = 950 / 10;
(new) digit = 950 % 2;
value == 95;
digit == 0;
call numString(95);
// Note: there is no case for 95 in numString so an empty string is returned.
The above iterations and variable values can be obtained with pen & paper (or a note pad). You can also do the same with something called a debugger.
I hope this helps.

Related

Stroustrup Ex.7, Chap.4 - C++ Syntax

I'm new to C++ and, as many others here, I'm trying to learn it from Bjarne Stroustrup's Programming -- Principles and Practice Using C++.
I'm stuck on Exercise 7, Chap.4., where the idea is to write a calculator that, when the input is either an integer and/or a string followed by a character (+,-,* or /), the output should announce "the sum/diff/prod/ratio of" input 1 and input 2 is the result; so if ("two" 3 *) is the input, the output should be "the product of 2 * 3 = 6".
Here's Stroustrup's solution (I'm leaving Stroustrup's comments):
-- There's no copyright infringement, as this is all from his website --
/*The solution uses two functions (in addition to main():
initialize_numbers() to initialize the vector of number string
representations
get_number() to read a number that is either a string or a sequence of
digits
*/
vector<string> numbers; // representation of numbers as strings
// numbers[i] is the string representation for i
// for numbers[0] to numbers[numbers.size()-1]
void initialize_numbers()
{
numbers.push_back("zero");
numbers.push_back("one");
numbers.push_back("two");
numbers.push_back("three");
numbers.push_back("four");
numbers.push_back("five");
numbers.push_back("six");
numbers.push_back("seven");
numbers.push_back("eight");
numbers.push_back("nine");
numbers.push_back("ten"); // why not? :-)
}
int get_number()
{
const int not_a_symbol = numbers.size(); // not_a_symbol is a value that does not correspond
// to a string in the numbers vector
int val = not_a_symbol;
if (cin>>val) return val; // try to read an integer composed of digits
cin.clear(); // clear string after failed attempt to read an integer
string s;
cin>>s;
for (int i=0; i<numbers.size(); ++i) // see if the string is in numbers
if (numbers[i]==s) val = i;
if (val==not_a_symbol) error("unexpected number string: ",s);
return val;
}
int main()
try
{ initialize_numbers();
cout<< "please enter two floating-point values separated by an operator\n The operator can be + - * / % : ";
while (true) { // "forever"; that is until we give an unacceptable input or make a computations error
int val1 = get_number();
char op = 0;
cin>>op; // get the operator
int val2 = get_number();
string oper; // text appropriate for an operator
double result;
switch (op) {
case '+':
oper = "sum of ";
result = val1+val2;
break;
case '-':
oper = "difference between ";
result = val1-val2;
break;
case '*':
oper = "product of ";
result = val1*val2;
break;
case '/':
oper = "ratio of ";
if (val2==0) error("trying to divide by zero");
result = val1/val2;
break;
case '%':
oper = "remainder of ";
if (val2==0) error("trying to divide by zero (%)");
result = val1%val2;
break;
default:
error("bad operator");
}
cout << oper << val1 << " and " << val2 << " is " << result << '\n';
cout << "Try again: ";
}
}
More specifically, my problem is with the following part:
int get_number()
{
const int not_a_symbol = numbers.size(); // not_a_symbol is a value that does not correspond
// to a string in the numbers vector
int val = not_a_symbol;
if (cin>>val) return val; // try to read an integer composed of digits
cin.clear(); // clear string after failed attempt to read an integer
etc etc etc...
}
I just don't understand what's going on here, in the big context. I'm having trouble understanding this whole get_number() function, and how it relates to the rest of the code.
1 - Why assign the value of number.size() to not_a_symbol? What does this accomplish?
2 - if (cin >> val) - why is that the conditional? val is == size of vector numbers, which is 11, so is the conditional the number 11? How is that helpful?
And what is it returning? Itself?
3 - // try to read an integer composed of digits - how is that accomplished, and why is that helpful?
Thank you, and sorry for the long format of the question.
In for that is in whole function get_number() i goes from 0 to one less than numbers.size() and puts i where input string not containing digits compared with one of strings in numbers vector into val(so you convert name of number into value of number). After that you check if val is same as size of vector numbers because if it is, there was no match(someone entered word that is not name of any number you can handle).
From if (cin >> x) - Why can you use that condition? cin>>val(cin reads from input into variable val) will return false if you enetred atleast one letter.
If you enter number with no letters you can return it (we want either string representing name of number or a normal digit).
Sorry to take away your answer, man, but I figured it out by myself, and the thing is much more simple (and clever).
The for-loop works as it should, comparing input strings to the strings inside the vector and returning the correspondent index number.
But the reason to assign the value of numbers.size() to not_a_symbol, giving val the value of numbers.size() resides in the fact that, if the first IF fails, and only then, the second will become true, since val was already initialized. That's why there's 2 separated IF statements, instead of an IF-ELSE: an ELSE would not make the previously initialized val count, because the input from string "s" would take over, preventing val's initial value to work on (val=not_a_symbol) inside the ELSE.
Forget the functions, put it all inside the main:
int main() {
vector<string> numbers{ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
int not = numbers.size();
int val = numbers.size(); //val is initialized
string s;
cin >> s;
for (int i = 0; i<numbers.size(); ++i)
if (numbers[i] == s) val = i; // first IF; if this condition is not met, it will return val as it was initialized (val=numbers.size() or 11)
if (val == not) val = 88; // then this condition will be checked. It will be true. It will return val = 88 (a random number);
cout << "val is: " << val << "\n" << "not is: " << not << "\n";
}
So, it's not a matter of comparing val with the vector's number of elements, is a matter of val already being equal to it and that fact acting upon the failing of the first condition.

Program that displays all multiples of 7 between 1 and 100 C++

How to write this program with switch condition statement instead of if?
#include <iostream>
using namespace std;
int main() {
int i;
for (i = 1; i <= 100; i++) {
if ((i % 7 == 0) && (i > 0)) {
cout << i << endl;
}
}
return 0;
}
The code you're looking for should be something like this:
#include <iostream> // this is for std::cin and std::cout (standard input and output)
using namespace std; // to shorten std::cout into cout
int main() {
cout << "multiples of 7 lower than 100 are:" << endl;
for ( int i=1 ; i<=100 ; i++ ) {
switch ( i%7 ) {
case 0: // this case 0 is similar to if ( i%7 == 0 )
cout << i << " ";
break;
default:
break;
}
}
cout << endl;
return 0;
}
The output will then be:
multiples of 7 lower than 100 are:
7 14 21 28 35 42 49 56 63 70 77 84 91 98
Here you are:
#include <iostream>
int main()
{
for (int i = 1; i<=100; i++)
{
switch(i % 7)
{
case 0:
std::cout << i << std::endl;
break;
default:
break;
}
}
return 0;
}
Online compilation: http://ideone.com/uq8Jue
It sounds like you are a little unfamiliar with a switch statement. A switch statement is like an if-else statement, except that it isn't a Boolean argument. So essentially it asks: Tell me the value of . And then for each case (possible outcome), it has a follow up action.
So you want to ask: tell me the value of the number, modulus 7. If it is zero, add one to the counter. If it is 1, do .
So your code should have a general structure of:
Switch(i%7):
Case 0{increment counter or display to std. out or store in array}
Case 1{other action}
It is possible to replace the if statement with switch/case statement for your case. But I think you have some misunderstanding about where to use if and where switch/case statements. I will suggest you use this statement as they are used in real life.
Use if, if you're going to check the condition. For example:
if (a > b){...} or if (a == 7){...} or if (functionReturnsTrue()){...}
The switch/case statement could be used when you have a set of conditions and the logic is different for each element in that set. For example:
enum HttpMethod {
GET,
POST,
PUT,
DELETE,
};
...
void handleHttpRequest(HttpRequest req)
{
...
switch(req.getHttpMethod())
{
case GET: handleGETRequest(req); break;
case POST: handlePOSTRequest(req); break;
case PUT: handlePUTRequest(req); break;
case DELETE: handleDELETERequest(req); break;
default: throw InvalidHttpMethod(); // in case when noone corresponds to the variable
}
}
Of course, you can write the same using if statement, but switch/case statement also have some compilation effects. When you switch the variable of enum type, you might get a compiler warning at least, if you dont check your variable for all possible flows.

A few errors - trying to convert Roman entry to Decimal

Just going to change my question for now - I could just use some guidance as to why I have three compiler errors in my program, not quite sure what I did wrong/am missing - I have added comments into the code just to state where they are. Thanks
#include <iostream>
#include <string>
using namespace std;
class romanType
{
public:
void setRomanNum(string store);
// this function will store the Roman numeral
int convertNum(char rNum);
// this function will convert the Roman numeral to a decimal
void decimalPrint(int total);
// this function will print the decimal number
void romanPrint(char rNum);
// this function will print the Roman numeral
int getNum(char letter);
// this function will get the number input
romanType(int store);
//Constructor with parameter
romanType();
char roman[7];
string num;
int length = 0;
string dNum;
int equals;
};
romanType::romanType(int store)
{
dNum = 1;
}
void romanType::setRomanNum (string store)
{
dNum = store;
}
void romanType::romanPrint(char rNum)
{
cout << "The Roman numeral is: " << roman << endl;
}
void romanType::decimalPrint(int total)
{
cout << "The Decimal number is: " << equals << endl;
}
int romanType::convertNum (char rNum)
{
int letter;
int totalNum = 0;
for (int i = 0; i< dNum.length(); i++)
// "loop will run at most once (loop increment never executed)"?
{
switch (roman[i])
{
case 'M':
totalNum+= 1000;
break;
case 'D':
totalNum += 500;
break;
case 'C':
totalNum += 100;
break;
case 'L':
totalNum += 50;
break;
case 'X':
totalNum += 10;
break;
case 'V':
totalNum += 5;
break;
case 'I':
totalNum += 1;
break;
}
totalNum = totalNum + letter;
equals = totalNum;
return equals;
}
};
// "control may reach end of non-void function"
int main()
{
romanType output;
int rNumeral;
char entry;
cout << "Please enter a Roman numeral (Capitalized only): " << endl;
cin >> rNumeral;
cout << "Print Decimal or Roman Numeral? Type 1 for Decimal, 2 for Roman Numeral: " << endl;
cin >> entry;
if (entry == '1')
{
cout << "You chose to view the decimal conversion." << endl;
output.decimalPrint(rNum);
// How do I output the decimal conversion from the void romanType::decimalPrint(int total) function?
}
else if (entry == '2')
{
cout << "You chose to view the Roman numeral." << endl;
output.romanPrint(rNumeral);
}
else
cout << "Error: bad input" << endl;
return 0;
exit(1);
}
The mistake in the algorithm is that the Roman system is non-positional. See en.wikipedia.org/wiki/Roman_numerals and en.wikipedia.org/wiki/Subtractive_notation. You can't just add up consequent digits (i.e. letters) but you also have to identify and account for the cases when subtraction takes place.
why am I getting the error "no matching constructor for initialization of "roman type"?
Because the only provided constructor is not the default one, but takes one parameter of type int. Since such a constructor was provided, the default constructor wasn't generated by the compiler. Define romanType::romanType() or change the existing one to romanType::romanType(int i = 0) (add a default parameter). See Is there an implicit default constructor in C++? and why default constructor is not available by default in some case
expected expression?
Provide braces around the preceding else block. More than one statement -> braces required.
if (entry == '1') {
cout << "You chose to view the decimal conversion." << endl;
output.decimalPrint(rNum);
} else if (entry == '2')
cout << "You chose to view the Roman numeral." << endl;
output.romanPrint(rNumeral);
}
"control may reach end of non-void function"
This is a warning only, but it will turn into an error if you include the -Werror flag that tells the compiler to treat all warnings as errors.
Ok I was wrong on this one. Actually the trick is that it is (in theory) possible that the romanType::convertNum(int) function follows a route where the for loop will never get executed and thus no return statement will be executed either. That's bad since the function is declared to return int hence there must be present an explicit return statement that (surprise) would return a value. Move the return out of the loop. This error is also closely related to the next one, discussed below.
"loop will run at most once (loop increment never executed)"?
This is because the return statement is placed incorrectly: inside the for loop not outside of it, and inside the function body. Hence the loop runs once and the function returns. Move the return statement. Credit to #ATN_LR_boom for noticing this!
Also, please get in the habit of formatting code properly. It will save you a lot of headache down the way.
Other than that, I'd use a std::map for the conversion function, it's shorter and more clear to the reader compared to the switch statement. Something along the lines of
int romanType::convertNum(int rNum) {
const static std::map<char, int> conversion = {
{'M', 1000},
{'D', 500},
// more mappings
{'I', 1}
};
if ((auto it = conversion.find(rNum)) != conversion.end())
return it->second;
else
return -1;
}
Your logic for the switch is wrong, try something like this:
int totalNum = 0;
for (int i = 0; i< dNum.length(); i++)
// the loop ran once because you were returning values when catching a letter
{
switch (roman[i])
{
case 'M': // roman[i] is a char, the cases should try to catch chars
totalNum += 1000; // increment your global number
break;
case 'D':
totalNum += 500;
break;
...
}
return totalNum;

C++ switch statement odd output

I'm working on a final assignment for an Intro to C++ course. What I've coded so far works, but it's producing some interesting output that I'm looking for clarification on. Here's my code:
(Caveat: Yes, I know using void main() sucks, but we're using Visual Studio in class, and this is the instructors preference.)
#include <string>
#include <iostream>
using namespace std;
void conversion(int);
void main()
{
int decimal_number, answer;
cout << "Please enter a whole decimal number (e.g. 20): ";
cin >> decimal_number;
if (decimal_number == 0)
{
answer = 0;
cout << "The hexadecimal value of your number is: " << answer;
getchar();
getchar();
}
else if (decimal_number < 0)
{
cout << "INVALID ENTRY" ;
getchar();
getchar();
}
else if (decimal_number > 0)
{
conversion(decimal_number);
}
getchar();
getchar();
}
void conversion (int decimal_number)
{
int count = 0, remainder, reverse_order;
char hexadecimal_number[10] = { NULL };
while (decimal_number != 0)
{
remainder = decimal_number % 16;
switch (remainder)
{
case 0:
hexadecimal_number[count] = '0';
count++;
break;
case 1:
hexadecimal_number[count] = '1';
count++;
break;
case 2:
hexadecimal_number[count] = '2';
count++;
break;
case 3:
hexadecimal_number[count] = '3';
count++;
break;
case 4:
hexadecimal_number[count] = '4';
count++;
break;
case 5:
hexadecimal_number[count] = '5';
count++;
break;
case 6:
hexadecimal_number[count] = '6';
count++;
break;
case 7:
hexadecimal_number[count] = '7';
count++;
break;
case 8:
hexadecimal_number[count] = '8';
count++;
break;
case 9:
hexadecimal_number[count] = '9';
count++;
break;
case 10:
hexadecimal_number[count] = 'A';
count++;
break;
case 11:
hexadecimal_number[count] = 'B';
count++;
break;
case 12:
hexadecimal_number[count] = 'C';
count++;
break;
case 13:
hexadecimal_number[count] = 'D';
count++;
break;
case 14:
hexadecimal_number[count] = 'E';
count++;
break;
case 15:
hexadecimal_number[count] = 'F';
count++;
break;
default:
cout << decimal_number << "+++ " << hexadecimal_number;
cout << "INVALID ENTRY";
getchar();
getchar();
}
decimal_number = decimal_number / 16;
}
cout << "The hexadecimal value of your number is: ";
for (reverse_order = count -1; reverse_order >= 0; reverse_order--)
{
cout << hexadecimal_number[reverse_order];
}
getchar();
getchar();
}
So, like I said: my code works. I can take any number input as a decimal, and convert it to its hexadecimal equivalent. However, I've found that I've had to include an IF statement within the main function of the code, because if the user inputs anything other than a decimal number into the decimal_number variable, the program will store a string of decimal numbers, into decimal_number, and I have no idea where those numbers come from. They don't appear to be the ASCII equivalents of anything.
... If none of this makes any sense, I'm sorry. just input cout << decimal_number after the line cin >> decimal_number, then run the code and see what weird number comes out. I hope that makes things clearer.
Anyway, my instructors stumped, and I'm stumped. I've got the above workaround in place that the instructor will accept, but for my own sanity, I just want to figure out what's going on. Any help or pointers is appreciated. Cheers!
You can test whether the result of cin >> decimal_number succeeded, like
if(!(cin>>decimal_number))
throw std::runtime_error("Oops, not a decimal number!");
This is a bit too extreme, you can also validate the input:
while(!(cin>>decimal_number))
{
std::cout << "Not decimal, input again ";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
If you're not performing this kind of validation, then you leave the stream in an invalid state whenever reading a non-decimal, and the variable you think you're reading into will end up un-initialized.
However, I've found that I've had to include an IF statement within the main function of the code, because if the user inputs anything other than a decimal number into the decimal_number variable, the program will store a string of decimal numbers, into decimal_number, and I have no idea where those numbers come from.
Well, you did not initialise decimal_number to anything, and you do not have any error checking around the cin >> decimal_number call. So I'm not sure what else you expected but an unspecified value for decimal_number!
Your instructor should know this. It's worrying that, on top of teaching you to write code that is ill-formed per the International Standard (void main!!), they failed to discover this problem or note that you have no error checking.
What's the point of the assignment?
The conversion can be simplified to:
cout << hex << decimal_value << endl;
Or if you need it in a string:
std::string convert_decimal_to_hex_string(int decimal_value)
{
std::ostringstream output;
output << hex << value;
return output.str();
}
I believe the class should show you how to use std::string and existing language features (such as the hex manipulator). Using char for a string is dangerous.
Also, since you don't know the size or limit of the decimal values, you will need to dynamically allocate (i.e. during run-time) the array holding the characters. Think about allocating 2 characters and entering the value 1024; buffer overflow.
Change your program to use std::string. Refrain from character (C-Style) arrays.

Adding a number to a word to call up a variable

Please be nice I am a total newby.
I have a list of variables (strings) from num1 to num90. I need to call these from a function by adding the number in an int to the word num.
The task is to convert digits to words from 'jumping into c++'...I might not be going about it in the 'right' way but this part has been stopping me for a while now!!
I'm trying like this:
#include <iostream>
#include <string>
using namespace std;
// Hard code numbers to 20 and then in tens to 90
string num1 = "one";
string num2 = "two";
string num3 = "three";
string num4 = "four";
string num5 = "five";
string num6 = "six";
string num7 = "seven";
string num8 = "eight";
string num9 = "nine";
Etc...up to 90
int main ()
{
// Break the number down into three digit blocks
int num = 0;
cout << "Please enter the number: ";
cin >> num;
while (num > 999)
{
int digit = (num % 1000);
num = ((num - digit)/1000);
//cout << digit << '\n';
//cout << num << '\n';
// For each block of numbers work out hundreds,
if (digit > 100)
{
int i = digit;
int j = (i % 100);
cout << num.append(j) << " hundred";
}
What I need to happen is the number stored in 'j' to be tagged onto the word num in order to call the string num*.
Is this possible?
Sure, use a map:
#include <map>
#include <string>
#include <iostream>
std::map<int, std::string> words { { 1, "one" }, { 2, "two" }, { 3, "three" } };
int main()
{
std::cout << words[1] << std::endl;
}
You'll probably have to deal with some special cases (up to twenty?), and you need a word for "hundred", etc. If you want to make it internationalizable, you'll have to think even harder.
What I need to happen is the number stored in 'j' to be tagged onto
the word num in order to call the string num*.
The trouble with that approach is that any variable names you use in your code are not compiled: when the program runs it will manipulate the values of your variables, but it doesn't know or care that you decided to use the name "num3" instead of "numero3" or "foobar".
If you want to make a link between a digit (3) and a string ("three") then you can use a Vector (as #Mark suggests, although you'll have problems after 20) or better still a Map (as #Kerrek suggests): these will work because in both cases the strings are referenced by the value of a variable (eg the value of digit in lookup[digit], or the literal value 1 in words[1]) rather than by the name of a variable.
EDIT:
For interest, here's a version using 'if' and 'switch'...
#include <iostream>
#include <string>
using namespace std;
string units2word(int units){
switch (units){
case 0: return "zero";
case 1: return "one";
case 2: return "two";
case 3: return "three";
// etc ...
case 18: return "eighteen";
case 19: return "nineteen";
}
}
string tens2word(int tens){
switch(tens){
case 2: return "twenty";
case 3: return "thirty";
// etc ...
case 9: return "ninety";
}
}
string num2words(int num) {
if (num > 99 && num%100 == 0) return units2word(num/100) + " hundred";
if (num > 99) return units2word(num/100) + " hundred and " + num2words(num%100);
if (num < 20) return units2word(num);
if (num%10 == 0) return tens2word(num/10);
return tens2word(num/10) +"-"+ units2word(num%10);
}
int main(int argc, char *argv[]) {
int num = -1;
while( num < 0 || num > 999){
cout << "Please enter a number between 0 and 999: ";
cin >> num;
}
cout << "You typed: " << num2words(num) << endl;
}
You should look at using std::vector. This gives you a variable that takes an index
std::vector<std::string> lookup;
lookup.push_back( "zero" ); // starts at lookup[0]
lookup.push_back( "one" );
lookup.push_back( "two" );
// etc
// then
std::cout << lookup[digit] << std::endl;
std::cout << lookup[num] << std::endl;