How do I convert a std::string to an uint64_t? I would also like the function to throw if the string does not contain a pure representation of an uint64_t. For example, conversions of these should throw:
"NO: 9889"
"9889L"
"9889U"
"1e+22"
or indicate by another means that they are not a pure representation. I am using C++98 and boost (including boost::regex).
Use boost::lexical_cast. It will throw a bad_lexical_cast if the number can't be parsed or overflows.
If you ever switch to C++11, there's a new function in the standard for that which should be faster.
A for with isdigit() followed by a strtoll() is always an option.
Perhaps not a one-liner, but a good function to write in your stringutils.cpp.
Related
So I've looked around for how to convert a string to a short and found a lot on how to convert a string to an integer. I would leave a question as a comment on those threads, but I don't have enough reputation. So, what I want to do is convert a string to a short, because the number should never go above three or below zero and shorts save memory (as far as I'm aware).
To be clear, I'm not referring to ASCII codes.
Another thing I want to be able to do is to check if the conversion of the string to the short fails, because I'll be using a string which consists of a users input.
I know I can do this with a while loop, but if there's a built in function to do this in C++ that would be just as, or more, efficient than a while loop, I would love to hear about it.
Basically, an std::stos function is missing for unknown reasons, but you can easily roll your own. Use std::stoi to convert to int, check value against short boundaries given by e.g. std::numeric_limits<short>, throw std::range_error if it's not in range, otherwise return that value. There.
If you already have the Boost library installed you might use boost::lexical_cast for convenience, but otherwise I would avoid it (mainly for the verbosity and library dependency, and it's also a little inefficient).
Earlier boost::lexical_cast was known for not being very efficient, I believe because it was based internally on stringstreams, but as reported in comments here the modern version is faster than conversion via stringstream, and for that matter than via scanf.
An efficient way is to use boost::lexical_cast:
short myShort = boost::lexical_cast<short>(myString);
You will need to install boost library and the following include: #include <boost/lexical_cast.hpp>
You should catch bad_lexical_cast in case the cast fails:
try
{
short myShort = boost::lexical_cast<short>(myString);
}
catch(bad_lexical_cast &)
{
// Do something
}
You can also use ssprintf with the %hi format specifier.
Example:
short port;
char szPort[] = "80";
sscanf(szPort, "%hi", &port);
the number should never go above three or below zero
If you really really need to save memory, then this will also fit in a char (regardless whether char is signed or unsigned).
Another 'extreme' trick: if you can trust there are no weird things like "002" then what you have is a single character string. If that is the case, and you really really need performance, try:
char result = (char)( *ptr_c_string - '0' );
I want to parse a file and use an std::stringstream to parse its contents. I use get() to read it character by character, which yields an std::stringstream::int_type. Now in certain cases I want to use a lookup table to convert ascii characters into other values (for example, to deterime whether a certain character is allowed in an identifier or not).
Now can I assume that the values I get from get() are non-negative, unless it is std::stringstream::traits_type::eof()? (And hence use them as indices for the lookup tables).
I couldn't find anything in the standard regarding that, which might be due to a lack of understanding on my part how this whole bytes to characters thing works in C++.
First let look at the more general case of basic_stringstream.
You can't assume that eof() is negative (I see the constraint nowhere and the C standard states The value of the macro WEOF may differ from that of EOF and need not be negative.)
In general, int_type comes from the trait parameter and the description of int_type for character traits doesn't mandate that to_int_type returns something positive.
Now, stringsteam is basic_stringstream<char> and thus use char_traits<char>; eof is negative but I haven't found a mandate that to_int_type has to non-negative values (it isn't in 21.2.3.1 and I see no way to deduce it from other constraints), but I wonder if I miss something as my expectation was that to_int_type(c) had to be equivalent to (int)(unsigned char)c -- it is the case for the GNU standard C++ library and I somewhat expect to get the same behavior as in C where functions taking or returning characters in int return non-negative values for characters.)
For information, the other standard specialization of char_traits:
char_traits<char16_t> and char_traits<char32_t> have an unsigned int_type, so even eof() is positive;
char_traits<wchar_t>::to_int_type isn't mandated to return a positive value for non eof() input either (but in contrast with char_traits<char> I didn't expect such mandate to be there).
I have an input file (ASCII) with arithmetics, e.g.
TEST;0.0;0.0+0.1;0.0+0.2
I can read the string and split it accordingly, so I already have elements of std::string. Now I wanted to use boost::lexical_cast<double> to store it in a double, comparable to an expression like:
double d = boost::lexical_cast<double>("0.0+0.1");
However, Boost throws
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_lexical_cast> >'
what(): bad lexical cast: source type value could not be interpreted as target
Is there a good way to go, maybe without sscanf? (If sscanf would be capable of doing this at all...)
TIA
boost::lexical_cast is not a parser/calculator. You could use Boost.Spirit to do this. There's an O'Reilley example on how to implement such a calculator, but as you can see it's not straight-forward.
Questions OpenSouce C/C++ Math expression parser Library and Evaluating arithmetic expressions in C++ might be good starting points if you want to implement a simple parser.
A solution could be splitting the strings again, if there's an arithmetic operator in the string, do the cast for both substrings and then do the arithemtic operation.
I don't think boost::lexical_cast or anything similar does this or is intended to do this.
what is the best way to call a function with the following declaration
string Extract(const char* pattern,const char* input);
i use
string str=Extract("something","input text");
is there a problem with this usage
should i use the following
char pattern[]="something";
char input[]="input";
//or use pointers with new operator and copy then free?
the both works but i like the first one but i want to know the best practice.
A literal string (e.g. "something") works just fine as a const char* argument to a function call.
The first method, i.e. passing them literally in, is usually preferable.
There are occasions though where you don't want your strings hard-coded into the text. In some ways you can say that, a bit like magic numbers, they are magic words / phrases. So you prefer to use constant identifier to store the values and pass those in instead.
This would happen often when:
1. a word has a special meaning, and is passed in many times in the code to have that meaning.
or
2. the word may be cryptic in some way and a constant identifier may be more descriptive
Unless you plain to have duplicates of the same strings, or alter those strings, I'm a fan of the first way (passing the literals directly), it means less dotting about code to find what the parameters actually are, it also means less work in passing parameters.
Seeing as this is tagged for C++, passing the literals directly allows you to easily switch the function parameters to std::string with little effort.
must you convert from strings to double? if so. how?
Are there functions for trig that will accept textbox string data as is?
Is there a way to pull the data from the textbox as a numeric value, not as a string?
must you convert from strings to double? if so. how?
Yes. There are quite a few ways to do this.
Are there functions for trig that will accept textbox string data as is?
No, but if you really wanted one, you could easily implement such a function using one of the techniques described in the aforementioned question.
Usually you want to validate user input to be sure it is correct before you use it, and validation of the input in numeric form is much easier than validation of the raw string.
Is there a way to pull the data from the textbox as a numeric value, not as a string?
Maybe; it depends entirely on what GUI framework you are using.
must you convert from strings to double?
Yes.
if so. how?
The C++ way is to use the string streams; in particular, you'll probably want to use istringstream. A viable alternative is to follow the C way, i.e. use sscanf with the appropriate format specifier ("%f").
Another C++ option is to use the boost lexical_cast, but starting to use boost just for lexical_cast is a bit overkill in my opinion.
Example with istringstream:
#include <sstream>
// ...
std::istringstream strParser(yourString);
double yourDouble;
strParser>>yourDouble;
if(strParser.fail())
{
// the string couldn't be converted to a double
}
else if(!strParser.eof())
{
// the string hasn't been fully consumed; this may or may not be a problem, depending on your needs
}
Are there functions for trig that will accept textbox string data as is?
AFAIK no, there's no need of them (although you can write them quite easily).
Is there a way to pull the data from the textbox as a numeric value, not as a string?
The WinAPIs provide a handful of such "convenience functions" for use in dialogs, but the only one I can recall that provides such help is GetDlgItemInt, which, as the name may suggest, works only for integers.
Addendum
I see now that you are using C++/CLI (you mentioned System::String): well, you should have said that, this changes the options quite a bit.
In the managed world, your best option is to use the Double::Parse method; to catch bad-formatted strings, you should either catch the exceptions thrown by Double::Parse or call Double::TryParse before calling Double::Parse.
Addendum bis
Uh, I forgot, since you're using the .NET Framework probably it should be better to use the .NET trigonometric functions (class System.Math).
I'd recommend using strtod
char *str = ...;
const char *end;
double d = strtod(str, &end);
if (*end != '\0')
{
// questionable data
}
There's no way to do a straight conversion from textbox to double as far as I know. You'll need to first convert to a double with something like strtod.
You could easily make a generic function which accepts a textbox control as an argument and returns a double (assuming it's the textbox contains a valid number) mind you..