stringstream: dec int to hex to car conversion issue - c++

I was trying some simple exercises with stringstream, when I came across this problem. Following program takes an int number, saves it in stringstream in hex format and then displays whether a int in decimal and char are available in string.
I ran it for different inputs and it is not working properly for some of them.
Please see the detail below code:
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main() {
int roll;
stringstream str_stream;
cout << "enter an integer\n";
cin>>roll;
str_stream << hex << roll;
if(str_stream>>dec>>roll){
cout << "value of int is " << roll << "\n";
}
else
cout << "int not fount \n";
char y;
if(str_stream>>y){
cout << "value of char is "<< y << endl;
}
else
cout << "char not found \n";
cout << str_stream.str() << "\n";
}
I ran it for 3 different inputs:
Case1:
{
enter an integer
9
value of int is 9
char not found
9
Case2:
enter an integer
31
value of int is 1
value of char is f
1f
Case3:
enter an integer
12
int not fount
char not found
c
In case 1 &2. program is working as expected but in case 3, it should found a char, I am not sure why it is not able to find char in stream.
Regards,
Navnish

If if(str_stream>>dec>>roll) fails to read anything then the state of the stream is set to fail(false). After that any further read operation using that stream will not be successful(and returns false) unless you reset the state of the stream using clear().
So:
.....//other code
if(str_stream>>dec>>roll){
cout << "value of int is " << roll << "\n";
}
else
{
cout << "int not fount \n";
str_stream.clear();//*******clears the state of the stream,after reading failed*********
}
char y;
if(str_stream>>y){
cout << "value of char is "<< y << endl;
}
else
cout << "char not found \n";
....//other code

Related

Can't compare string with while and if statements

I'm trying to create a command menu where the user will be able to perform as many commands as he/she wants until pressing "q" which will end the loop. I think I have everything I need to do this except I realized mid-way that my professor asked to use string. When I included string into the program, I began to get error messages saying "could not convert string to bool" wherever there was a while or if statement. What can I do to fix this problem and get my program working. Thanks in advance.
#include <iostream>
#include <string>
using namespace std;
int main()
{
char option;
char number=0;
string s;
string n;
string p;
string q;
char number2;
cout << " Please enter a number: "<< endl;
cin >> number;
do {
cout << " Please enter a command: " << endl;
cout << " s- square the number " << endl;
cout << " n- add the number and (number +1) " << endl;
cout << " p- add the number and (number -1) " << endl;
cout << " q- quit" << endl;
cin >> option;
if (option=s) {
s= number*number;
cout << "Square of this number is : " << s;
}
else if ( option=n){
number2= number+1;
n= number+number2;
cout << "Sum of" << number << "+" << number2 << "is: " << n;
}
else if (option=p) {
number2= number-1;
p= number+number2;
cout << "Sum of" << number << "+" << number2 << "is" << p;
}
else if (option=q)
cout << "Terminating Program";
} while(option);
return 0;
}
you're assigning in the if and else if rather than comparing.
if (option=s) {
should be
if (option=='s') {
note the double =
Also, you need to put single quotes (') around the character choice.
It's a common mistake that even experienced developers make.
These declarations
char number=0;
string s;
string n;
string p;
string q;
char number2;
should all be int
int number=0;
int s;
int n;
int p;
int q;
int number2;
Let me answer as if I were who will evaluate your homework. You have several issues here:
You are asked to use string. Avoid the use of char and string together.
char option; // professor asked to use string: (-1) point
string option; // ok
When you use a single =, like in option="a", you are assigning the value "a" to the variable option. But in the if-else statements you want to compare, so you should use the == comparison operator. Also, you can't compare a char with a string.
if(option = "a") // error: expression must have bool type: (-2) points
if(option == 'a') // error: no operator "==" matches std::string == char; (-2) points
if(option == "a") // ok
You use while(option), but option is declared as a char, not as a bool. Replace this line to while(option!="q") to finish when you enter q.
while(option); // error: expression must have bool type; (-2) points
while(option != "q"); // GOOD!
Also, your program will finish when you scape from the while-statement; so, try to put the "Terminating Program" message after this.
You do not need to declare such many variables (s, n, p, q, number2). Try to use temporary variables inside each scope, for example:
if (option=="s")
{
cout << "Square of this number is : " << number*number << endl;
}
else if ( option=="n")
{
int number2= number+1;
cout << "Sum of " << number << "+" << number2 << " is : " << number+number2 << endl;
}
In the form you write this code, every time you type a new option you will obtain an output like:
Sum of 10+11 is : 21 Please enter a command:
This is ugly to me (-1 point). Try to put a newline (<< endl;) after every cout lines.
Finally, what if I type any other letter not listed in the menu? I would expect a message like Enter a valid option (-1 point).

std::_throw_out_of_range occurs from nowhere

I'm an absolute beginner in c++. Literally. It's just been a week.
Today I was writing a program to test how many iterations are needed to make a certain number palindromic.
Here is the code:
#include <iostream>
#include <string>
#include <algorithm>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers 1 to 1000
*/
using namespace std;
class number
{
public:
string value;
void reverse();
};
void number::reverse()
{
std::reverse(value.begin(),value.end());
}
void palindrome(number num)
{
string n=num.value;
number reversenum, numsum, numsumreverse;
reversenum=num;
reversenum.reverse();
numsum.value=num.value;
numsumreverse.value=numsum.value;
numsumreverse.reverse();
int i=0;
while (numsum.value.compare(numsumreverse.value) !=0)
{
reversenum=num;
reversenum.reverse();
numsum.value=to_string(stoll(num.value,0,10)+stoll(reversenum.value,0,10));
numsumreverse.value=numsum.value;
numsumreverse.reverse();
num.value=numsum.value;
i++;
}
cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
}
int main()
{
number temp;
int i;
for (i=1; i<1001; i++)
{
temp.value=to_string(i);
palindrome(temp);
}
return 0;
}
It goes on smooth for numbers upto 195. But, in case of 196 I get an error.
It says:
terminate called after throwing an instance of 'std::out_of_range'
what(): stoll
I cannot make out what to do. I tried starting from 196 but the error persisted. Any help will be greatly appreciated. :)
UPDATE: This time I tried to do it using ttmath library. But arghs! It again stops at 195 and doesn't even report an error! I might be doing something foolish. Any comments would be appreciated. Here's the updated code:
#include <iostream>
#include <string>
#include <algorithm>
#include <ttmath/ttmath.h>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers 1 to 1000
*/
using namespace std;
class number
{
public:
string value;
void reverse();
};
void number::reverse()
{
std::reverse(value.begin(),value.end());
}
template <typename NumTy>
string String(const NumTy& Num)
{
stringstream StrStream;
StrStream << Num;
return (StrStream.str());
}
void palindrome(number num)
{
string n=num.value;
number reversenum, numsum, numsumreverse;
reversenum=num;
reversenum.reverse();
numsum.value=num.value;
numsumreverse.value=numsum.value;
numsumreverse.reverse();
ttmath::UInt<100> tempsum, numint, reversenumint;
int i=0;
while (numsum.value.compare(numsumreverse.value) !=0)
{
reversenum=num;
reversenum.reverse();
numint=num.value;
reversenumint=reversenum.value;
tempsum=numint+reversenumint;
numsum.value=String<ttmath::UInt<100> >(tempsum);
numsumreverse.value=numsum.value;
numsumreverse.reverse();
num.value=numsum.value;
i++;
}
cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
}
int main()
{
number temp;
int i;
for (i=196; i<1001; i++)
{
temp.value=to_string(i);
palindrome(temp);
}
return 0;
}
UPDATE: It's solved. Some research suggested that 196 might be a Lychrel Number. And the result I was getting after implying the ttmath library is just reassuring that my algorithm works. I have tried it out for all the numbers upto 10000 and it gave out the perfect results. Here is the final code:
#include <iostream>
#include <string>
#include <algorithm>
#include <ttmath/ttmath.h>
#include <limits>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers inside a desired range
*/
using namespace std;
string LychrelList;
int LychrelCount=0;
class number
{
public:
string value;
void reverse();
};
void number::reverse()
{
std::reverse(value.begin(),value.end());
}
template <typename NumTy>
string String(const NumTy& Num)
{
stringstream StrStream;
StrStream << Num;
return (StrStream.str());
}
void palindrome(number num)
{
string n=num.value;
number reversenum, numsum, numsumreverse;
reversenum=num;
reversenum.reverse();
numsum.value=num.value;
numsumreverse.value=numsum.value;
numsumreverse.reverse();
ttmath::UInt<100> tempsum, numint, reversenumint;
int i=0;
while ((numsum.value.compare(numsumreverse.value) !=0) && i<200)
{
reversenum=num;
reversenum.reverse();
numint=num.value;
reversenumint=reversenum.value;
tempsum=numint+reversenumint;
numsum.value=String<ttmath::UInt<100> >(tempsum);
numsumreverse.value=numsum.value;
numsumreverse.reverse();
num.value=numsum.value;
i++;
}
if (i<200) cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
else
{
cout << "A solution for " << n << " could not be found!!!" << endl;
LychrelList=LychrelList+n+" ";
LychrelCount++;
}
}
int main()
{
cout << "From where to start?" << endl << ">";
int lbd,ubd;
cin >> lbd;
cout << endl << "And where to stop?" << endl <<">";
cin >> ubd;
cout << endl;
number temp;
int i;
for (i=lbd; i<=ubd; i++)
{
temp.value=to_string(i);
palindrome(temp);
}
if (LychrelList.compare("") !=0) cout << "The possible Lychrel numbers found in the range are:" << endl << LychrelList << endl << "Total - " << LychrelCount;
cout << endl << endl << "Press ENTER to end the program...";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
string s;
getline(cin,s);
cout << "Thanks for using!";
return 0;
}
It's a really awesome community. Special thanks to Marco A. :)
UPDATE AGAIN: I've devised my own add() function that cuts the program's dependency on external libraries. It resulted in a smaller executable and faster performance too. Here is the code:
#include <iostream>
#include <string>
#include <algorithm>
#include <limits>
/* This program calculates the steps needed
to make a certain number palindromic.
It is designed to output the values for
numbers inside a desired range
*/
using namespace std;
string LychrelList;
int LychrelCount=0;
string add(string sA, string sB)
{
int iTemp=0;
string sAns;
int k=sA.length()-sB.length();
int i;
if (k>0){for (i=0;i<k;i++) {sB="0"+sB;}}
if (k<0) {for (i=0;i<-k;i++) {sA="0"+sA;}}
for (i=sA.length()-1;i>=0;i--)
{
iTemp+=sA[i]+sB[i]-96;
if (iTemp>9)
{
sAns=to_string(iTemp%10)+sAns;
iTemp/=10;
}
else
{
sAns=to_string(iTemp)+sAns;
iTemp=0;
}
}
if (iTemp>0) {sAns=to_string(iTemp)+sAns;}
return sAns;
}
void palindrome(string num)
{
string n=num;
string reversenum, numsum, numsumreverse;
numsum=num;
numsumreverse=numsum;
reverse(numsumreverse.begin(),numsumreverse.end());
int i=0;
while ((numsum.compare(numsumreverse) !=0) && i<200)
{
reversenum=num;
reverse(reversenum.begin(),reversenum.end());
numsum=add(num,reversenum);
numsumreverse=numsum;
reverse(numsumreverse.begin(),numsumreverse.end());
num=numsum;
i++;
}
if (i<200) cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num << endl;
else
{
cout << "A solution for " << n << " could not be found!!!" << endl;
LychrelList=LychrelList+n+" ";
LychrelCount++;
}
}
int main()
{
cout << "From where to start?" << endl << ">";
int lbd,ubd;
cin >> lbd;
cout << endl << "And where to stop?" << endl <<">";
cin >> ubd;
cout << endl;
string temp;
int i;
for (i=lbd; i<=ubd; i++)
{
temp=to_string(i);
palindrome(temp);
}
if (LychrelList.compare("") !=0) cout << "The possible Lychrel numbers found in the range are:" << endl << LychrelList << endl << "Total - " << LychrelCount;
cout << endl << endl << "Press ENTER to end the program...";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
string s;
getline(cin,s);
cout <<endl << "Thanks for using!";
return 0;
}
You guys here have helped me a lot to find my own way. Thanks everyone. :)
You're overflowing long long since the last two valid values of num.value and reversenum.value are 7197630720180367016 and 6107630810270367917 which, added together, are way above the maximum size of a long long (9223372036854775807 on my machine). That will yield a negative value and spoil your next call to stoll
std::out_of_range is thrown if the converted value would fall out of the range of the result type or if the underlying function (std::strtol or std::strtoll) sets errno to ERANGE.
(reference)
If you're trying to get the next smallest palindrome, you should use another approach like the one I explained here.
You can find a Live Example here
If you prefer to/must continue with your approach you should either do the addition manually on the strings or use a bigint library (again take a look at here and modify the plusOne() function to your liking)
From http://www.cplusplus.com/reference/string/stoll/
If the value read is out of the range of representable values by a long long, an out_of_range exception is thrown.
The ll data type cant handle the string length. My debugger tells me 196 breaks on the value
std::stoll (__str=\"9605805010994805921-\", __idx=0x0, __base=10)
The long long is too small.
You might want to do the addition on the strings themselves, without resorting to a numeric type.

How to implement throw statement to do a integer value

I have a question that might be very simple to many of you however, I have not found an answer to my question.
I have the program below that is working properly. This code turns a number into a floating number and integer.
Let's say you entered 5.4, the program will give you 5.4 for double and 5 for integer.
Now I need to add a throw catch statement to my program in case the user enters a text instead of a number ("If the conversion fails, throw an exception and allow the user to re-enter the value.").
This is the pseudocode of what I need to do.
try {
if(num ==character)
throw;
cout << "\n The number entered " << num << "invalid, please enter again";
}
catch
{
}
and I implemented something like this, however it did not work. I set the 'a' variable character thinking the user has to enter a text in order to get that message. However it did not work and gave some errors.
try
{
char a;
if (num == a)
throw num;
}
catch(int e)
{
cout << "A number of " << a << " is invalid." << endl;
cout << "Please re-enter a number: ";
cin << num
}
I am very new with this "try,throw,catch" terms. I would be happy if you help me through this, thanks.
#include <C:\\CSIS1600\MyCppUtils.cpp>
#include <iostream>
#include <string>
using namespace myNameSpace;
int main()
{
runner("is running");
cout << "Enter a number : ";
string num;
getline(cin, num);
cout<< "double " << getValidDouble(num) << endl;
cout<< "integer " << getValidInt(num) << endl;
system("pause");
return 0;
}
#include<iostream>
#include<string>
using namespace std;
namespace myNameSpace
{
string num;
void runner(string str)
{
cout <<"runner-3() is running.."<<endl;
}
int getValidInt(string n)
{
int valueint;
valueint=atoi(n.c_str());
return valueint;
}
double getValidDouble(string n )
{
double valuedouble;
valuedouble = atof(n.c_str());
return valuedouble;
}
}
You can use Boost to do a lexical cast. If you have valid input (e.g. 2.54), no exception will be thrown, but with invalid input (e.g. 2???54) the bad_lexical cast is thrown:
#include <boost/lexical_cast.hpp>
try
{
double x1 = boost::lexical_cast<double> ("2.54");
double x2 = boost::lexical_cast<double> ("2???54");
cout << x1 << x2 << endl;
}
catch(boost::bad_lexical_cast& e)
{
cout << "Exception caught - " << e.what() << endl;
}

Currency Conversion Program

I'm working on a currency converter program that converts the old system of British pounds, Shillings, and pence, into their new system, which is a type of Decimal Pound. Where 100 pence equals a pound. Here is the code for the program
#include <iostream>
#include <iomanip>
#include <conio.h>
using namespace std;
int calcNum(int pound, int shilling, int pence)
{
pence = pound*240 + shilling*12 + pence;
return pence;
}
int calcNew(int total_pence, double dec_pound)
{
dec_pound = total_pence / 240;
return dec_pound;
}
int main()
{
int pence;
int shilling;
int pound;
const int OLD_POUND = 240;
const int OLD_SHILLING = 12;
double total_pence;
double dec_pound = 0;
double deci_pound;
cout << "Please Enter the Amount of old pounds: ";
cin >> pound;
cout << endl;
if(cin.fail())
{
cout << "That's not a valid number\n";
cout << "This program will terminate on any keypress!";
_getch();
exit(1);
}
cout << "Please Enter the Amount of old shillings: ";
cin >> shilling;
cout << endl;
if(cin.fail())
{
cout << "That's not a valid number\n";
cout << "This program will terminate on any keypress!";
_getch();
exit(1);
}
cout << "Please Enter the Amount of old pence: ";
cin >> pence;
cout << endl;
if(cin.fail())
{
cout << "That's not a valid number\n";
cout << "This program will terminate on any keypress!";
_getch();
exit(1);
}
total_pence = calcNum(pence, shilling, pound);
deci_pound = calcNew(dec_pound, total_pence);
cout << (5, "\n");
cout << "The total amount in decimal pounds is: ";
cout << setprecision(2) << "\x9c" << deci_pound;
_getch();
return 0;
}
When I run this program however, I'm having a bit of a problem. No matter what the number input is, it always says 0 pounds. Just to make sure that the setprecision function at the end wasn't interfering with the code, I had originally set a cout statement with a _getch() after the two functions to show how much deci_pound came out to be calculated to, and once again, it came out as zero. So my issue seems to be somewhere in the functions running the calculations. If someone could help me with this, I would really appreciate it.
Your calcNew(...) function returns an int, make it return a double. Right now it casts to int which involves stripping the decimals.
In your code, dec_pound is set equal to zero, and you're deci_pound = calcNew(dec_pound, total_pence), which divides 0 by 240 = 0.
The order of the parameters when you call both functions is wrong. Your functions are declared and implemented as:
int calcNum(int pound, int shilling, int pence);
int calcNew(int total_pence, double dec_pound);
And then you call them like this:
total_pence = calcNum(pence, shilling, pound);
deci_pound = calcNew(dec_pound, total_pence);

Convert a letter to its ascii decimal form

i am in a basic programming class and know practically nothing about programming, we are using c++ and my current project is to pull up the console and do the following
input a letter and output its ascii decimal equivalent
input a number between 33 and 254 and output its letter equivalent
input a lower case letter and output itscapital
input a number of hours and output the number of minutes
input a number greater than 60 and output the number of hours and minutes
this is the work i have so far
#include <iostream>
using namespace std;
void main ()
{
cout<<"Assignment 2"<<endl;
char somechar;
int charval;
int input_number;
char output_letter2;
char input_lower_letter;
char output_upper_letter;
int input_hours;
int output_minutes;
int input_minutes2;
int output_hours2;
int output_remainder_minutes;
cout<<"Enter a letter"<<endl;
cin>>somechar>>endl;
cout<< somechar='a';
int charval = somechar;
printf("%c = %d\n",somechar,charval);
system("pause");
}
any tips and help are deeply appreciated
One crucial lesson (which they never seem to teach in school) is to start with a very simple program, get it working perfectly, then build up, testing at every step.
Your code doesn't compile. Let's strip your code down and start from scratch:
void main()
{
}
This doesn't compile. Fix it:
int main()
{
return(0);
}
Now add some output:
#include <iostream>
using namespace std;
int main()
{
cout << "Assignment 2" << endl;
return(0);
}
So far, so good. Now input:
#include <iostream>
using namespace std;
int main()
{
cout << "Assignment 2" << endl;
char somechar;
cout << "Enter a letter" << endl;
cin >> somechar >> endl;
return(0);
}
This doesn't compile. Fix it.
And so on. See how it works?
#include <iostream>
using namespace std;
int main() {
char a ='a';
cout << a << " => integer: " << (int)(a) << endl;
int i = 98;
cout << i << " => character: " << (char)(i) << endl;
char b='b';
cout << b <<" => lower: " << (char)(b+('a'-'A')) << endl;
char c='c';
cout << c << " => upper: " << (char)(c-('a'-'A')) << endl;
int hours = 15;
cout << hours << " hours => minutes: " << hours * 60 << endl;
int minutes = 75;
cout << minutes << " minutes => hours:minutes: " << minutes/60 << ":" << minutes % 60 << endl;
system("PAUSE");
return 0;
}
For this you can take a look at casting. To cast a character (char) to an integer ASCII value, you have to cast an int on that char value. For example:
#include <iostream>
using namespace std;
int main() {
char myvalue;
cout<<"Enter a character: ";
cin>>myvalue;
cout<<endl<<"The ASCII value is: "<<(int)myvalue<<endl;
return 0;
}
Now because this is homework, I wont finish the steps for you, but it should be pretty straight forward from here.
For more information about casting, I highly suggest: http://www.cplusplus.com/doc/tutorial/typecasting/