Infinite output when I print a variable inside a loop - c++

I'm trying to convert a number input to words. I am a beginner so my code might look clunky. I also apologise for posting such a large code.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int main()
{
int i = 0, number = 0;
string num_name = "";
cout << "Enter a number (maximum value is 1,000,000,000)" << endl;
cin >> number;
//To find the maximum magnitude
while ((number / pow(10, i)) >= 1)
{
i++;
}
i--;
int j = i;
cout << j << endl; //Check
//To find which multiple of 3 i is
int n = 0;
while (j >= 3)
{
if (j % 3 == 0)
n++;
j--;
}
j = i;
cout << j << endl; //Check
cout << n << endl; //Check
//String construction
int k = n;
int q = 0;
while (k >= 1)
{
while (j >= (3 * k))
{
q = (int)(number / pow(10, j));
if (j == 2 + (3 * k))
{
if (q == 1) num_name += "one";
else if (q == 2) num_name += "two";
else if (q == 3) num_name += "three";
else if (q == 4) num_name += "four";
else if (q == 5) num_name += "five";
else if (q == 6) num_name += "six";
else if (q == 7) num_name += "seven";
else if (q == 8) num_name += "eight";
else if (q == 9) num_name += "nine";
num_name += "hundred";
}
if (j == 1 + (3 * k))
continue;
if (j == 3 * k)
{
if (q == 1) num_name += "one";
else if (q == 2) num_name += "two";
else if (q == 3) num_name += "three";
else if (q == 4) num_name += "four";
else if (q == 5) num_name += "five";
else if (q == 6) num_name += "six";
else if (q == 7) num_name += "seven";
else if (q == 8) num_name += "eight";
else if (q == 9) num_name += "nine";
else if (q == 10) num_name += "ten";
else if (q == 11) num_name += "eleven";
else if (q == 12) num_name += "twelve";
else if (q == 13) num_name += "thirteen";
else if (q == 14) num_name += "fourteen";
else if (q == 15) num_name += "fifteen";
else if (q == 16) num_name += "sixteen";
else if (q == 17) num_name += "seventeen";
else if (q == 18) num_name += "eighteen";
else if (q == 19) num_name += "nineteen";
if (q >= 20 && q <= 99)
{
int r = 0;
r = q % 10;
(int)(q /= 10);
if (q == 2) num_name += "twenty";
else if (q == 3) num_name += "thirty";
else if (q == 4) num_name += "forty";
else if (q == 5) num_name += "fifty";
else if (q == 6) num_name += "sixty";
else if (q == 7) num_name += "seventy";
else if (q == 8) num_name += "eighty";
else if (q == 9) num_name += "ninety";
if (r == 1) num_name += "one";
else if (r == 2) num_name += "two";
else if (r == 3) num_name += "three";
else if (r == 4) num_name += "four";
else if (r == 5) num_name += "five";
else if (r == 6) num_name += "six";
else if (r == 7) num_name += "seven";
else if (r == 8) num_name += "eight";
else if (r == 9) num_name += "nine";
}
if (k == 3) num_name += "billion";
else if (k == 2) num_name += "million";
else if (k == 1) num_name += "thousand";
}
number = number % (int)pow(10, j);
j--;
}
k--;
}
cout << num_name << endl;
cin.ignore();
cin.get();
return 0;
}
The loop at the "String Construction" section crashes and is printing infinite values of the variable q (quotient). I have also tried printing a simple variable like flag = 1 before q and that too is giving infinite 1s. I cannot figure out what is causing this. Any input would be greatly helpful for my learning!

Well, one of the best things you can do is do not messy the main function. You messed the main function :c
It's a great idea create functions that allow you to solve your problem with less code. The number of function to create is subjective, imho it would bo good create 2 function: toDigit and convert, both return strings.
Also i would use a function for the logaritm and for the power without use the libraries (mainly because power return a double that you have to convert it to int, the math library is weighty and other reason)
Let's start: (All the function must be above the main function and toDigit must be above convert)
You can get the magnitude of the number with a rudimental logaritmic function that give you a bad apporximation, beacuse of that i've called it sillyLog:
int sillyLog(int n, int b){
return !(n/b < 1)? 1 + sillyLog(n/b, b) : 1;
}
Then we create our function for the power:
int power(int b, int e){
return (e < 1)? 1 : b * power(b, e-1);
}
Now let's see the main:
int main(){
int number = 0, magnitude = 0, counter = 1;
string num_name = "";
cout << "Enter a number (maximum value is 2,147,483,647)" << endl;
cin >> number;
magnitude = sillyLog(number, 10);
while (magnitude - 3 > 0){
magnitude = magnitude - 3;
counter++;
}
while (number){
int tmp;
tmp = (number - (number % power(1000,--counter)))/ power(1000, counter);//remove all digit after the first three and decrease counter
num_name += convert(tmp, counter + 1);
number = number - tmp * power(1000, counter); // we cut the first 3 digit
}
cout << num_name << endl;
return 0;
}
counter is the variable that count triplets,
also 2,147,483,647 is the max length for the integer type, if you want a bigger number you have to use a long/long long/unsigned/ other types.
NB: negative numbers aren't a problem because you simply ignore them but they "eat" half of your memory dedicated to the number.
How you can see we generate our string simply calling the function convert
string convert(int n, int m){
string s = "";
s = ((n-n%100)/100)? toDigit((n-n%100)/100) + " hundred " : "";
s += toDigit(n - (n - n%100));
switch (m){
case 4: return s + " billion ";
case 3: return s + " million ";
case 2: return s + " thousand ";
default: return s;
}
}
I've used the conditional operator (ternary) and the switch case instead of the if just to let you know about their existence here
Now let's see the heaviest function that we can't simplify :c
string toDigit(int n){
if (n < 20)
switch (n){
case 1: return "one ";
case 2: return "two ";
case 3: return "three ";
case 4: return "four ";
case 5: return "five ";
case 6: return "six ";
case 7: return "seven ";
case 8: return "eight ";
case 9: return "nine ";
case 10: return "ten ";
case 11: return "eleven ";
case 12: return "twelve ";
case 13: return "thirteen ";
case 14: return "fourteen ";
case 15: return "fifteen ";
case 16: return "sixteen ";
case 17: return "seventeen ";
case 18: return "eighteen ";
case 19: return "nineteen ";
default: return "";
}
switch ((n - n%10) / 10){
case 2: return "twenty " + toDigit(n - (n - n % 10));
case 3: return "thirty " + toDigit(n - (n - n % 10));
case 4: return "forty " + toDigit(n - (n - n % 10));
case 5: return "fifty " + toDigit(n - (n - n % 10));
case 6: return "sixty " + toDigit(n - (n - n % 10));
case 7: return "seventy " + toDigit(n - (n - n % 10));
case 8: return "eighty " + toDigit(n - (n - n % 10));
case 9: return "ninety " + toDigit(n - (n - n % 10));
}
}
Here is a MUST use the switch case to make readable your code
If you have any doubt i'll answer you gladly

Related

DiceSum - How to extend if/ if-else statement to reroll dice if dice sum is not a certain number

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <iomanip>
using namespace std;
int main()
{
int n;
int win = 0;
int lose = 0;
int dice1;
int dice2;
int diceSum;
srand(time(0));
cout << "How many turns would you like? ";
cin >> n;
for (int i = 1; i <= n; i++)
{
dice1 = rand()%6 + 1;
dice2 = rand()%6 + 1;
diceSum = dice1 + dice2;
if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){
win++;
}
else if((diceSum == 7) || (diceSum == 11)){
lose++;
}
else{
}
}
cout << "No. of Wins: " << win << endl;
cout << "No. of Losses: " << lose << endl;
cout<< setprecision(4)<<fixed<<showpoint;
cout << "\nThe experimental probability of winning "<< (static_cast<float>(win)/n)*100 <<
"%.\n";
return 0;
}
My assignments states that "...can be shown analytically that the long term probability of winning the dice game you have programmed in PA 8-3 is .4929293. Extend that program you wrote to run a large number of turns and calculate the empirical (experimental) probability." My last assignment I had to make a program to roll two die and reveal the dice sum. If it was a 2, 3, or 12, I won; if it was a 7 or 11 it was a loss, otherwise it would repeat the roll. I was unable to repeat the roll, now for this assignment, I have to do the same thing.This is my output from my current code
I you want to not take into account the cases where the sum is not 2,3,12,7 or 11 you have lot of possibilities, for instance :
closer to your code do i -=1; in the empty else {}
for (int i = 1; i <= n; i++)
{
dice1 = rand()%6 + 1;
dice2 = rand()%6 + 1;
diceSum = dice1 + dice2;
if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){
win++;
}
else if((diceSum == 7) || (diceSum == 11)){
lose++;
}
else{
i -= 1;
}
}
or increment i only when you win or lose and remove i++ in the for()
for (int i = 1; i <= n;)
{
dice1 = rand()%6 + 1;
dice2 = rand()%6 + 1;
diceSum = dice1 + dice2;
if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){
win++;
i++;
}
else if((diceSum == 7) || (diceSum == 11)){
lose++;
i++;
}
}
or the variant
i = n;
for (;;)
{
dice1 = rand()%6 + 1;
dice2 = rand()%6 + 1;
diceSum = dice1 + dice2;
if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){
win++;
if (!--i)
break;
}
else if((diceSum == 7) || (diceSum == 11)){
lose++;
if (!--i)
break;
}
}
or remove all about i and replace your for by do { dice1 = ..... } while ((win + lose) != n); without having the last else branch
do {
dice1 = rand()%6 + 1;
dice2 = rand()%6 + 1;
diceSum = dice1 + dice2;
if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){
win++;
}
else if((diceSum == 7) || (diceSum == 11)){
lose++;
}
} while ((win + lose) != n);
or the variant
for (;;) {
dice1 = rand()%6 + 1;
dice2 = rand()%6 + 1;
diceSum = dice1 + dice2;
if((diceSum == 2) || (diceSum == 3) || (diceSum == 12)){
if ((++win + lose) == n)
break;
}
else if((diceSum == 7) || (diceSum == 11)){
if ((++lose + win) == n)
break;
}
}
Example of execution whatever the way :
pi#raspberrypi:/tmp $ ./a.out
How many turns would you like? 1000
No. of Wins: 336
No. of Losses: 664
The experimental probability of winning 33.6000%.
This result it normal even it seems opposite of the intuition because the possibilities to make these numbers are :
2 : 1+1
3 : 1+2 2+1
12 : 6+6
and
7: 1+6 6+1 2+5 5+2 3+4 4+3
11 : 5+6 6+5
so 4 possibilities to win ( 1/3/12 ) and 8 possibilities to lose ( 7/11 ), so the probability to lose if two times more than the probability to win
I encourage you to always check the input, replacing
cin >> n;
by something like
if (!(cin >> n)) {
cerr << "invalid number" << endl;
return -1;
}

How to Find All TRUE Conditions and Concatenate Corresponding Variables into New Variable?

a = 4
b = 5
c = 7
if (a >= 4){
text1 = “a is high”;
}
if (b >= 8){
text2 = “b is high”;
}
if (c >= 6){
text3 = “c is high”;
}
In C or C++, how would I find which of these statements are true (a & c) and create a new variable that concatenates their accompanying variables containing text to produce a result like “a is high and c is high”? The next time the code executes it may find that only a is high, or whatever the case may be. How would I go about doing this?
Use a single variable and keep on appending as you get the required information.
string text1;
if (a >= 4)
text1.append("a is high");
if (b >= 8)
{
if(text1.length()!=0)
text1.append(" and ");
text1.append("b is high");
}
if (c <= 6)
{
if(text1.length()!=0)
text1.append(" and ");
text1.append("c is high");
}
The answer of Gaurav Sehgal is elegant. Here is another way of writing it-
C++
string text = "";
if (a >= 4)
text += "a is high";
if (b >= 8)
{
if(text.size() > 0)
text += " and ";
text += "b is high";
}
if (c <= 6)
{
if(text.size() > 0)
text += " and ";
text += "c is high";
}
C
char text[buf_size] = {'\0'};
if (a >= 4)
strcat(text, "a is high");
if (b >= 8)
{
if(strlen(text) > 0)
strcat(text, " and ");
strcat(text, "b is high");
}
if (c <= 6)
{
if(strlen(text) > 0)
strcat(text, " and ");
strcat(text, "c is high");
}
create a temporary variable as result.
a = 4
b = 5
c = 7
result="";
if (a >= 4){
result += “a is high”;
}
if (b >= 8){
if(result==""){
result += “b is high”;
}else{
result += “and b is high”;
}
}
if (c <= 6){
if(result==""){
result += “c is high”;
}else{
result += “and c is high”;
}
}
text1=result
Using numeric comparison operators as well as logical AND ("&&"), the following C code finds all true conditions while obviating the need for a new variable as it efficiently uses text1, text2 and text3. Note, the result avoids any duplicate output:
#include <stdio.h>
#include <string.h>
int main(void) {
int a = 4;
int b = 5;
int c = 7;
char text1[] = "a is high";
char text2[] = "b is high";
char text3[] = "c is high";
if ( a >= 4 && c < 6){
puts(text1);
}
if (b >= 8){
puts(text2);
}
if (c >= 6 && a < 4) {
puts(text3);
}
if( ( a >= 4 ) && ( c >= 6 ) ) {
strcat(text1," and ");
strcat(text1,text3);
puts(text1);
}
return 0;
}
See demo

Converting int to roman numerals, only end if zero entered [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 6 years ago.
I need to convert int to Roman numerals, my code is failing to compile with mingw using
C:\code>g++ -Wall -o rome_to_int rome_to_int.cpp
C:\Users\vm1\AppData\Local\Temp\ccSvDFll.o:task2.cpp:(.text+0x1278): undefined r
eference to `get_int_ref_checked()'
collect2.exe: error: ld returned 1 exit status
Now as part of the code, it must keep asking for input, converting that input untill zero is entered. Once Zero has been entered then it can exit.
I must use code from a privius question which covers the continuing untill which is found in the get_int_ref_checked, I can assume ONLY integers will be entered and nothing else, no doubles nor string of words.
I'm not sure what else to check.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int get_int_ref_checked();
string int_to_ROMAN();
/**
Turns the number from 1 to 9
*/
string digit_name(int digit)
{
if (digit == 1) return "I";
if (digit == 2) return "II";
if (digit == 3) return "III";
if (digit == 4) return "IV";
if (digit == 5) return "V";
if (digit == 6) return "VI";
if (digit == 7) return "VII";
if (digit == 8) return "VIII";
if (digit == 9) return "IX";
return "";
}
/**
Turns the number 10, 20, 30, 40, 50, 60, 70, 80, 90
*/
string ten_name(int n)
{
if (n == 1) return "X";
if (n == 2) return "XX";
if (n == 3) return "XXX";
if (n == 4) return "XL";
if (n == 5) return "L";
if (n == 6) return "LX";
if (n == 7) return "LXX";
if (n == 8) return "LXXX";
if (n == 9) return "XC";
return "";
}
/**
Turns the number 100, 200, 300, 400, 500, 600, 700, 800, 900
*/
string hun_name(int n)
{
if (n == 1) return "C";
if (n == 2) return "CC";
if (n == 3) return "CCC";
if (n == 4) return "CD";
if (n == 5) return "D";
if (n == 6) return "DC";
if (n == 7) return "DCC";
if (n == 8) return "DCCC";
if (n == 9) return "CM";
return "";
}
/**
Turns the number 1000, 2000, 3000
*/
string thou_name(int n)
{
if (n == 1) return "M";
if (n == 2) return "MM";
if (n == 3) return "MMM";
return "";
}
string int_to_ROMAN(int n)
{
int part = n; // The part that still needs to be converted
string roman; // The return value
if (part >= 1000)
{
roman = thou_name(part / 1000);
part = part % 1000;
}
if (part >= 100)
{
roman = roman + hun_name(part/100);
part = part % 100;
}
if (part >= 10)
{
roman = roman + ten_name(part/10);
part = part % 10;
}
if (part > 0)
{
roman = roman + digit_name(part);
}
return roman;
}
int main()
{
int n;
string r;
n = get_int_ref_checked();
if (n == 0)
{
cout<< "The intput is ZERO! ";
}
if(n > 0)
{
cout<< "The convert is " << int_to_ROMAN(n);
}
return 0;
}
void get_int_ref_checked(int& n) {
for(;;) // infinite loop
{
cout<< "Please enter an integer\n";
std::string inp;
std::stringstream ss;
ss << inp;
if( !(ss >> n) || n >= 4000 || n <= 0)
{
cout << "Error enter a number n: 0 < n < 4000: \n";
}
}
}
You are forward declaring the function int get_int_ref_checked() but there is no implementation, as int get_int_ref_checked(int& n) is another function, which is not being forward declared and so results in the error your seeing.

Am I using this switch case incorrectly?

So the idea of this program is to get the users input in the form of a Roman Numeral up to 4999. I decided to use a switch case to loop through an string of input. The problem is when I put in a value like 99 which would be XCIX it returns -101. Any help is grateful.
int number = 0, M = 1000, D = 500, C = 100, L = 50, X = 10, V = 5, I = 1;
for (int i = 0; i < roman.length(); i++)
{
switch (roman[i])
{
case 'M': number += 1000; break;
case 'D': if (roman[i + 1] != 'D' && i + 1 < roman.size())
number -= 500;
else
number += 500;
break;
case 'C': if (roman[i + 1] != 'C' && i + 1 < roman.size())
number -= 100;
else
number += 100;
break;
case 'L': if (roman[i + 1] != 'L' && i + 1 < roman.size())
number -= 50;
else
number += 50;
break;
case 'X': if (roman[i + 1] != 'X' && i + 1 < roman.size())
number -= 10;
else
number += 10;
break;
case 'V': if (roman[i + 1] != 'V' && i + 1 < roman.size())
number -= 5;
else
number += 5;
break;
case 'I':
if (roman[i + 1] != 'I' && i + 1 < roman.size())
number -= 1;
else
number += 1;
break;
}
}
return number;
Roman numerals count negative only when they appear before a digit with higher value. Being different is not enough.

I keep getting a 'no match for call to' error

#include <iostream>
#include <string>
using namespace std;
// Turns a digit between 1 and 9 into its english name
// Turn a number into its english name
string int_name(int n)
{
string digit_name;
{
if (n == 1) return "one";
else if (n == 2) return "two";
else if (n == 3) return "three";
else if (n == 4) return "four";
else if (n == 5) return "five";
else if (n == 6) return "six";
else if (n == 7) return "seven";
else if (n == 8) return "eight";
else if (n == 9) return "nine";
return "";
}
string teen_name;
{
if (n == 10) return "ten";
else if (n == 11) return "eleven";
else if (n == 12) return "twelve";
else if (n == 13) return "thirteen";
else if (n == 14) return "fourteen";
else if (n == 14) return "fourteen";
else if (n == 15) return "fifteen";
else if (n == 16) return "sixteen";
else if (n == 17) return "seventeen";
else if (n == 18) return "eighteen";
else if (n == 19) return "nineteen";
return "";
}
string tens_name;
{
if (n == 2) return "twenty";
else if (n == 3) return "thirty";
else if (n == 4) return "forty";
else if (n == 5) return "fifty";
else if (n == 6) return "sixty";
else if (n == 7) return "seventy";
else if (n == 8) return "eighty";
else if (n == 9) return "ninety";
return "";
}
int c = n; // the part that still needs to be converted
string r; // the return value
if (c >= 1000)
{
r = int_name(c / 1000) + " thousand";
c = c % 1000;
}
if (c >= 100)
{
r = r + " " + digit_name(c / 100) + " hundred";
c = c % 100;
}
if (c >= 20)
{
r = r + " " + tens_name(c /10);
c = c % 10;
}
if (c >= 10)
{
r = r + " " + teen_name(c);
c = 0;
}
if (c > 0)
r = r + " " + digit_name(c);
return r;
}
int main()
{
int n;
cout << endl << endl;
cout << "Please enter a positive integer: ";
cin >> n;
cout << endl;
cout << int_name(n);
cout << endl << endl;
return 0;
}
I Keep getting this Error code:
intname2.cpp: In function âstd::string
int_name(int)â:
intname2.cpp:74: error: no match for
call to â(std::string) (int)â
intname2.cpp:80: error: no match for
call to â(std::string) (int)â
intname2.cpp:86: error: no match for
call to â(std::string) (int&)â
intname2.cpp:91: error: no match for
call to â(std::string) (int&)â
You are using digit_name, teen_name, etc as functions, when they are defined as variables. If you want to use them like that, you need to define them before your int_name function like this:
string digit_name(int n)
{
if (n == 1) return "one";
else if (n == 2) return "two";
else if (n == 3) return "three";
else if (n == 4) return "four";
else if (n == 5) return "five";
else if (n == 6) return "six";
else if (n == 7) return "seven";
else if (n == 8) return "eight";
else if (n == 9) return "nine";
return "";
}
Timothy, it looks like you're confused about the requirements of the assignment. Please make sure you understand the requirements, because at this stage it doesn't look like you know what's expected of you. You're trying to move the body of one function into the body of another function and that's simply not possible to do.
Please post the exact words that your teacher used in order for us to give you proper advice on the question.
Here are some tips for you:
If your teacher has covered switch statements then use switch statements.
Check if your teacher is not asking you to do function declarations.
Check if your teacher is not asking you to put the functions in libraries (a header file and source file).
OK scrap the tips... given your teacher's requirements I think it might look a little bit like this:
string int_name(int n)
{
int c = n; // the part that still needs to be converted
string r; // the return value
if (c >= 1000)
{
r = int_name(c / 1000) + " thousand";
c = c % 1000;
}
if (c >= 100)
{
// If you have covered switch statements then it will look like this
string digitName;
switch(c/100) // <- instead of calling digit_name(c/100), we call switch(c/100)
{
case 1:
// assign the digit name
digitName = "one";
break;
case 2:
//... fill here with your own code
break;
case 3:
//... fill here with your own code
break;
// write all the cases through 9
default:
digitName = "";
break;
}
// in the result string use the digitName variable
// instead of calling the digit_name function
r = r + " " + digitName + " hundred";
c = c % 100;
}
if (c >= 20)
{
r = r + " " + tens_name(c /10);
c = c % 10;
}
if (c >= 10)
{
r = r + " " + teen_name(c);
c = 0;
}
if (c > 0)
r = r + " " + digit_name(c);
return r;
}
Note that I'm using a switch statement, but if you your teacher hasn't shown you switch statements yet, then you can still use if/else statements:
string int_name(int n)
{
int c = n; // the part that still needs to be converted
string r; // the return value
if (c >= 1000)
{
r = int_name(c / 1000) + " thousand";
c = c % 1000;
}
if (c >= 100)
{
// declare a digitName
string digitName;
// declare a temporary value
int temp = c/100;
if(1 == temp)
{
// assign the digit name
digitName = "one";
}
else if( 2 == temp )
{
digitName = "two";
}
else if( 3 == temp )
{
// fill in the rest
}
else if( 4 == temp )
{
// fill in the rest
}
// write all the other else if statements
else
{
digitName = "":
}
// in the result string use the digitName variable
// instead of calling the digit_name function
r = r + " " + digitName + " hundred";
c = c % 100;
}
if (c >= 20)
{
r = r + " " + tens_name(c /10);
c = c % 10;
}
if (c >= 10)
{
r = r + " " + teen_name(c);
c = 0;
}
if (c > 0)
r = r + " " + digit_name(c);
return r;
}
You're going to have to take the first example with digit_name and apply it to tens_name and teen_name functions.
WARNING:
In reality you don't want to repeat the same code and clutter a single function with a bunch of code that could be in its own function. You ALWAYS want to break out repeating code into functions... if she's asking you to repeat code when you can use functions then you should be concerned. Ask your teacher if this is what she REALLY wants you to do!