Getting long long with suffix out of istringstream (C++) - c++

How come istringstream can't seem to fully read numeric literals with suffixes?
#include <iostream>
#include <sstream>
using namespace std;
int main() {
long long x = 123ULL; // shows 123ULL is a valid long long literal
istringstream iss("123ULL");
iss >> x;
cout << "x is " << x << endl;
char extra;
iss >> extra;
cout << "remaining characters: ";
while(!iss.eof())
{
cout << extra;
iss >> extra;
}
cout << endl;
return 0;
}
The output of this code is
x is 123
remaining characters: ULL
Is this behavior controlled by the locale? Could anyone point me to clear documentation on what strings are accepted by istringstream::operator>>(long long)?

Yes, it's controlled by the locale (via the num_get facet), but no locale I ever heard of supports C++ language literals, and it would be the wrong place to customize this.
Streams are for general-purpose I/O, and C++ integer literal suffixes are very specialized.
The exact behavior of the default num_get facet is described in the C++11 standard in section 22.4.2.1. The description partially references the strto* family of functions from the C standard library. You can find a somewhat condensed version here:
http://en.cppreference.com/w/cpp/locale/num_get/get

Related

Changing decimal dot to a comma

The code goes like this:
Input: Decimal number N, dot needs to be switched with notch, e.g. input: 0.36
output: 0,36
I have been thinking about it for a couple of hours already but can't figure how to solve it. Can someone help?
You can do this by setting the locale for the cin and cout streams using the std::imbue() function.
The following example uses the English/US (dot) decimal separator for input and the French (comma) for output; swapping the arguments for the two imbue calls will reverse this.
#include <iostream>
#include <locale>
int main()
{
std::cin.imbue(std::locale("en_US")); // Set INPUT to use the DOT
std::cout.imbue(std::locale("fr_FR")); // Set OUTPUT to use a COMMA
double test;
std::cout << "Enter a number: ";
std::cin >> test;
std::cout << "Number was: " << test << std::endl;
return 0;
}
The std::locale section of the C++ Standard Template Library provides numerous options for customising (and fine-tuning) numeric input/output formats, but the techniques it offers are not trivial to master.
You can read the number as text, and then use std::replace:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
std::string number;
std::cin >> number;
std::replace(number.begin(), number.end(), '.', ',');
std::cout << number << '\n';
}

Convert string Mac address to byte-array

I have a string (std::string) which contains a MAC address in C++, e.g.:
10:10:0F:A0:01:00
I need to convert it to an array of bytes (unsigned char*).
The bytes have to be written from left to right. Does anybody have a function or efficient algorithm for this?
Sorry for necroposting, but just to help others who may still be searching for the answer, there is a standard C way that still can be used in C++ without any reinvention of the wheel. Just man ether_aton or click here.
This'll work. You've tagged this as C++ so I've scrupulously avoided the shorter solution that's possible using the sscanf C method. using namespace std is used here only to shorten the quoted code.
#include <iostream>
#include <sstream>
main() {
unsigned char octets[6];
unsigned int value;
char ignore;
using namespace std;
istringstream iss("10:10:0F:A0:01:00",istringstream::in);
iss >> hex;
for(int i=0;i<5;i++) {
iss >> value >> ignore;
octets[i]=value;
}
iss >> value;
octets[5]=value;
// validate
for(int i=0;i<sizeof(octets)/sizeof(octets[0]);i++)
cout << hex << static_cast<unsigned int>(octets[i]) << " ";
cout << endl;
}

What exactly does stringstream do?

I am trying to learn C++ since yesterday and I am using this document: http://www.cplusplus.com/files/tutorial.pdf (page 32). I found a code in the document and I ran it. I tried inputting Rs 5.5 for price and an integer for quantity and the output was 0.
I tried inputting 5.5 and 6 and the output was correct.
// stringstreams
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main ()
{
string mystr;
float price = 0;
int quantity = 0;
cout << "Enter price: ";
getline (cin,mystr);
stringstream(mystr) >> price;
cout << "Enter quantity: ";
getline (cin,mystr);
stringstream(mystr) >> quantity;
cout << "Total price: " << price*quantity << endl;
return 0;
}
What exactly does the mystring command do? Quoting from the document:
"In this example, we acquire numeric values from the standard input
indirectly. Instead of extracting numeric values directly from the
standard input, we get lines from the standard input (cin) into a
string object (mystr), and then we extract the integer values from
this string into a variable of type int (quantity)."
My impression was that the function will take an integral part of a string and use that as input.
Sometimes it is very convenient to use stringstream to convert between strings and other numerical types. The usage of stringstream is similar to the usage of iostream, so it is not a burden to learn.
Stringstreams can be used to both read strings and write data into strings. It mainly functions with a string buffer, but without a real I/O channel.
The basic member functions of stringstream class are
str(), which returns the contents of its buffer in string type.
str(string), which set the contents of the buffer to the string argument.
Here is an example of how to use string streams.
ostringstream os;
os << "dec: " << 15 << " hex: " << std::hex << 15 << endl;
cout << os.str() << endl;
The result is dec: 15 hex: f.
istringstream is of more or less the same usage.
To summarize, stringstream is a convenient way to manipulate strings like an independent I/O device.
FYI, the inheritance relationships between the classes are:
From C++ Primer:
The istringstream type reads a string, ostringstream writes a string, and stringstream reads and writes the string.
I come across some cases where it is both convenient and concise to use stringstream.
case 1
It is from one of the solutions for this leetcode problem. It demonstrates a very suitable case where the use of stringstream is efficient and concise.
Suppose a and b are complex numbers expressed in string format, we want to get the result of multiplication of a and b also in string format. The code is as follows:
string a = "1+2i", b = "1+3i";
istringstream sa(a), sb(b);
ostringstream out;
int ra, ia, rb, ib;
char buff;
// only read integer values to get the real and imaginary part of
// of the original complex number
sa >> ra >> buff >> ia >> buff;
sb >> rb >> buff >> ib >> buff;
out << ra*rb-ia*ib << '+' << ra*ib+ia*rb << 'i';
// final result in string format
string result = out.str()
case 2
It is also from a leetcode problem that requires you to simplify the given path string, one of the solutions using stringstream is the most elegant that I have seen:
string simplifyPath(string path) {
string res, tmp;
vector<string> stk;
stringstream ss(path);
while(getline(ss,tmp,'/')) {
if (tmp == "" or tmp == ".") continue;
if (tmp == ".." and !stk.empty()) stk.pop_back();
else if (tmp != "..") stk.push_back(tmp);
}
for(auto str : stk) res += "/"+str;
return res.empty() ? "/" : res;
}
Without the use of stringstream, it would be difficult to write such concise code.
To answer the question. stringstream basically allows you to treat a string object like a stream, and use all stream functions and operators on it.
I saw it used mainly for the formatted output/input goodness.
One good example would be c++ implementation of converting number to stream object.
Possible example:
template <class T>
string num2str(const T& num, unsigned int prec = 12) {
string ret;
stringstream ss;
ios_base::fmtflags ff = ss.flags();
ff |= ios_base::floatfield;
ff |= ios_base::fixed;
ss.flags(ff);
ss.precision(prec);
ss << num;
ret = ss.str();
return ret;
};
Maybe it's a bit complicated but it is quite complex. You create stringstream object ss, modify its flags, put a number into it with operator<<, and extract it via str(). I guess that operator>> could be used.
Also in this example the string buffer is hidden and not used explicitly. But it would be too long of a post to write about every possible aspect and use-case.
Note: I probably stole it from someone on SO and refined, but I don't have original author noted.
You entered an alphanumeric and int, blank delimited in mystr.
You then tried to convert the first token (blank delimited) into an int.
The first token was RS which failed to convert to int, leaving a zero for myprice, and we all know what zero times anything yields.
When you only entered int values the second time, everything worked as you expected.
It was the spurious RS that caused your code to fail.

How to use cin with unknown input types?

I have a C++ program which needs to take user input. The user input will either be two ints (for example: 1 3) or it will be a char (for example: s).
I know I can get the twos ints like this:
cin >> x >> y;
But how do I go about getting the value of the cin if a char is input instead? I know cin.fail() will be called but when I call cin.get(), it does not retrieve the character that was input.
Thanks for the help!
Use std::getline to read the input into a string, then use std::istringstream to parse the values out.
You can do this in c++11. This solution is robust, will ignore spaces.
This is compiled with clang++-libc++ in ubuntu 13.10. Note that gcc doesn't have a full regex implementation yet, but you could use Boost.Regex as an alternative.
EDIT: Added negative numbers handling.
#include <regex>
#include <iostream>
#include <string>
#include <utility>
using namespace std;
int main() {
regex pattern(R"(\s*(-?\d+)\s+(-?\d+)\s*|\s*([[:alpha:]])\s*)");
string input;
smatch match;
char a_char;
pair<int, int> two_ints;
while (getline(cin, input)) {
if (regex_match(input, match, pattern)) {
if (match[3].matched) {
cout << match[3] << endl;
a_char = match[3].str()[0];
}
else {
cout << match[1] << " " << match[2] << endl;
two_ints = {stoi(match[1]), stoi(match[2])};
}
}
}
}

How can I check if a number (double type) stored as a string is a valid double number in C++?

I'm having an issue with a program I'm working on in C++. I am asking the user to input a valid number. I take it in as a string because the particular assignment I'm doing, it makes it easier in the long run. For basic error checking, I want to check to see if the number entered is a valid number. Example:
Enter number: 3.14
This would be valid
Enter number: 3.1456.365.12
This shouldn't be valid
use strtod, which converts a string to a double and returns any characters it couldn't interpret as part of the double.
double strtod(const char* nptr, char** endptr)
Like this:
char* input = "3.1456.365.12";
char* end;
strtod(input, &end);
if (*input == '\0')
{
printf("fail due to empty string\n");
}
if (end == input || *end != '\0')
{
printf("fail - the following characters are not part of a double\n%s\n", end);
}
I think boost::lexical_cast should help you here
An example using only standard C++:
#include <sstream>
// ...
double dbl = 0.0;
std::istringstream num("3.1456.365.12");
num >> dbl;
if(!num.fail() &&
num.eof()) // This second test is important! This makes sure that the entire string was converted to a number
{
// success
}
else
{
// failure
}
Bonus generic template function version:
#include <sstream>
#include <string>
#include <exception>
// Version that throws an exception on a bad parse:
template <typename T>
T parse(const std::string& str)
{
T value;
std::istringstream parser(str);
parser >> value;
if(!parser.fail() && parser.eof())
{
return value;
}
else
{
throw "bad lexical cast";
}
}
// usage:
double foo = parse<double>("3.14234");
// Non-exception, error code version
template <typename T>
bool parse(const std::string& str, T& value)
{
std::istringstream parser(str);
parser >> value;
return (!parser.fail() && parser.eof());
}
// usage:
double foo = 0.0;
bool success = parser<double>("3.11234", foo);
If you have no boost, you always can use strtod
You can use strtoX (where X is f for float, l for long, ul for unsigned long, etc.), choosing for the kind of number you want. One of the parameters you give it is an "end pointer", which points to the first character in the string that could not be converted into the target number type.
In your case, what you're apparently looking for is that the end pointer should be at the end of the string, indicating that all characters in the string were converted to the target type.
Edit: Sorry, didn't notice that you'd mentioned 'double' in the title (but not the question itself). That being the case, you'd use strtod, as a couple of others have also advised.
The best way is to make an actual attempt to convert your string to double using any of the standard and/or idiomatic ways to do the conversion, and check for errors afterwards. In C that would be functions from strto... group (which are, of course, perfectly usable in C++ as well). In C++ you can use stream-based conversion idiom.
One thing to watch for though is that the common convention in standard conversion methods is to convert "as much as possible" and not consider any extra characters as an error. For example, a string "123abc" is normally considered valid input, with only "123" part getting converted. All usable methods provide you with the way to detect the fact that there is something extra after the actual number, if you want to treat this situation as an error. But it is up to you to take the additional steps to perform this verification.
A simple option is to use the sscanf function:
const char * num_as_str = "3.1416";
double num;
if(std::sscanf(num_as_str, "%lg", &num) == 1)
{
std::cout << "You correctly entered the number " << num << "\n";
}
If you want to get fancy you can use istringstream:
std::istringstream iss(num_as_str);
if(iss >> num)
{
std::cout << "You correctly entered the number " << num << "\n";
}
If you want to get extra-fancy you can use boost's lexical_cast:
try
{
num = boost::lexical_cast<double>(num_as_str);
}
catch(boost::bad_lexical_cast &)
{
std::cout << "What you entered is not a proper number" << num << "\n";
}
Ah, I loved these assignments. A good old hand written lexer is the way to go (since you are still in the begining days -- don't try to use boost just yet). They are fast, easy to write and extremely fun to play with. If you can get a copy of Levine's book on Lex/Yacc, look up the first couple of chapters for ideas.
As mentioned by AndreyT, the best way is to attempt to convert the string into a float and check for an error. Personally I would opt to use std::istringstream, as you're using C++. Something like the following should work:
float ff;
std::istringstream istr;
std::string input("1234.5678");
// set the stream to have your string as its base
istr.str(input);
// now try to read the number:
istr >> ff;
if (istr.fail())
{
// some error in the parsing
}
istringstream is part of STL, so you shouldn't need any additional libraries, and it will also with with exceptions if that's your choice. More information can be found here: http://www.cplusplus.com/reference/iostream/istringstream/
You could use regular expressions. Since you already have a string, it would be easy to compare that with this regex:
/^\d+(\.\d+)?$/
The library regex.h can help you here. See this: regex.h
This is my quick hack :)
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
template <typename T>
bool fromStr(const std::string& str, T& var)
{
std::stringstream convertor;
convertor << str;
convertor >> var;
if( convertor.fail() )
return false;
char c = static_cast<char>( convertor.get() );
return convertor.eof() || c == '\n' || c == ' ' || c == '\t';
}
int main()
{
double d;
std::string str = "5.04146.55";
if( fromStr<double>(str, d) )
{
std::cout << "Valid conversion!, d = " << d;
}
else
{
std::cout << "Invalid conversion!";
}
}