Below code is used to get a std::string representation from ASCII code.
string Helpers::GetStringFromASCII(const int asciiCode) const
{
return string(1,char(asciiCode));
}
It works well. But in my application, I know the ASCII codes at compile time. So I will be calling it like
string str = GetStringFromASCII(175) // I know 175 at compile time
Question
Is there any way to make the GetStringFromASCII method a template so that the processing happens at compile time and I can avoid calling the function each time at runtime.
Any thoughts?
This kind of template meta programming works well when you're dealing with primitive data types like ints and floats. If you necessarily need a string object, you can't avoid calling the std::string constructor and there's no way that call can happen at compile time. Also, I don't think you can drag the cast to char to compile time either, which, in all, means that templates cannot help you here.
Instead of feeding an int constant to a string conversion function, use a string constant directly:
string str("\xAF"); // 0xAF = 175
By the way, except for heavy performance needs in a loop, trading code readability for some CPU cycles is rarely money effective overall.
Why are you even bothering with a helper function?
string s( 1, char(175) );
That's all you need and it's the quickest you're going to get.
How about something like this:
#include <iostream>
#include <string>
using namespace std;
template <int asciiCode>
inline string const &getStringFromASCII()
{
static string s(1,char(asciiCode));
return s;
}
int main(int, char const**) {
cout << getStringFromASCII<65>() << endl;
}
EDIT: returns a ref now
Related
I have a big read-only string that I scan for syntax and based on that simple syntax I extract a bunch of smaller strings that I use later for further processing. Based on testing, creating and copying most of the big string into the small strings is kind of a performance bottleneck (there are thousands of them per each big string).
I figured that I don't actually need to allocate for-, and copy the data though. What I really need is a sort of string snippet type instead that would only store a pointer to the start of the relevant data and the length but at the same time, it should be a drop-in replacement for std::string and all the standard library interactions it has.
That would be the easiest to implement anyways, I could roll my own class for that and implement the functions I need but if there is already something like it in the standard library then why bother.
So basically, is there a substring sort of class in STL?
Yes, since C++17 you have std::string_view.
Example:
#include <iostream>
#include <string>
#include <string_view>
int main() {
std::string foo = "Hello world";
std::string_view a(foo.c_str(), 5);
std::string_view b(foo.c_str() + 6, 5);
std::cout << a << '\n' // prints Hello
<< b << '\n'; // prints world
}
This is where using std::string_view instead of std::string is very beneficial in reducing copies of those original strings and being able to use std::string_view::substr.
Instead of copying the strings you are operating on, a string view provides a view to the underlying string - pretty much just the pointer to the start of the string and the size of it.
Hi i'm having trouble making a function that checks the data type of a variable and checks it to make sure if a data type is similar to it in C++. Here's my code so far:
#include <iostream>
#include <typeinfo>
using namespace std;
int main() {
int typeCheck(string words, string typeWanted);
//make number assurance function .
string word;
cin >> word;
typeCheck(word, "string");
}
int typeCheck(string words, string typeWanted) {
if (typeid(words).name() != typeid(typeWanted).name()) {
cin.clear();
cin.ignore();
return 0;
}
else if (typeid(words).name()== typeid(typeWanted).name())
cout << "All good";
}
When I run the code it keeps saying the same output which is: All good even if I put a string or an int when its not the correct one. Instead of saying this I want it to clear the buffer and ignore it. Can anyone help me with this problem? Thanks in advance!
C++ is a statically typed language, meaning that the type is known at compile time. It will never be known only at run time.
What that means is that in your example:
int typeCheck(string words, string typeWanted);
both words and typeWanted will always be strings. If it is ever not a string, it will fail to compile. Thus, using typeid() in this situation is somewhat pointless. Your if statement will always be false, and your else-if statement will always be true.
Instead, you would want to use typeid() when you don't know they will be the same type, like in some sort of template situation:
template <class WordsType, class TypeWantedType>
int typeCheck(WordsType words, TypeWantedType typeWanted);
Here, a typeid() comparison makes more sense, because you don't really know if words and typeWanted are both strings.
You could do something like this instead:
template <class WordsType>
int typeCheck(WordsType words, string typeWanted) {
if (typeid(words).name() != typeWanted) {
//...
}
// ...
}
This would compare an unknown type to a wanted type.
Finally, there is another option, #RSahu's option from the comments:
if(words == typeWanted) {
//...
}
This will compare the input the user gave to the string "string".
It's unclear to me what you want to do exactly, so I can't recommend which one you should use, but at least now you have a couple of options.
It is because you are converting the type to string eaither way so it will allways trigger as correct as long as it is a string in the function input.
I would recommend that you use a template type so that whatever you enter into the TypeCheck() function will retain its type.
The following code snippet can do hash value on a string object. I would like to get hash value a binary string (a pointer and length). I know I can form a string object with pointer and length, but there is extra overhead to form a string only for that. Wonder if it's possible to use the std hash function with two parameters: pointer and length.
Thanks.
#include <iostream>
#include <functional>
#include <string>
int main()
{
std::string str = "Meet the new boss...";
std::hash<std::string> hash_fn;
std::size_t str_hash = hash_fn(str);
std::cout << str_hash << '\n';
}
I found this article in stack overflow which shows that the underlying hash function is actually a function of the bytes in the string's internal buffer:
What is the default hash function used in C++ std::unordered_map?
But rather than risk undefined behaviour by calling into internal functions within the standard library, why not ask the question, "how much performance will I lose by creating a std::string"? Given that you can always create such a string as a static const (zero overhead) I wonder what you're actually going to save?
Please help.
I have this program from here that calls a function in a header file.
#include <iostream>
#include "md5.h"
#include <string>
using namespace std;
int main(){
string x;
char* v_MD5String;
MD5 md5 ;
v_MD5String = "Hello World";
x = puts(md5.digestString(v_MD5String));
cout << x;
return 0;}
The function called:
char* digestString( char *string ){
Init() ;
Update( (unsigned char*)string, strlen(string) ) ;
Final() ;
return digestChars ;}
The above works, however when I use input from the user it compiles, but the run crashes without any errors.
In the program, this is changed:
v_MD5String = "Hello World";
to this:
cin >> v_MD5String;
What should I do to get this to work?
Thanks.
So, if I understand correctly, you have the following function declared in a header file which you cannot modify:
char* digestString( char *string );
You should first know that this is questionable coding style. The function takes a char * rather than a char const *, which implies that the passed data is changed, yet it also returns something. I had to dig around in the implementation posted on the page you linked to find out that string is really an input parameter, so that the author just forgot about using const and the data is not going to be changed anyway.
(The data not going to be modified is at least my assumption upon superficial code analysis and some compile tests. You should ask the author to be really sure!)
If you use this function in C++, your first task should be to provide a safer, easy-to-understand wrapper function which uses real C++ strings (the std::string class), not C strings (which happen to be completely unencapsulated pointers to characters in memory, which is fine in the C world but not in C++). You already use one std::string in your program. That's good. Now use it more:
std::string SafeDigestString(MD5 &md5, std::string const &input)
{
// the input of digestString will never be modified:
return md5.digestString(const_cast<char *>(input.c_str()));
}
Both the const & and the parameter name make it clear that we are dealing with input.
Note that I used a const_cast<char *> to pass the std::string's C-compatible data representation, which is char const *, to the digestString function. This is one of the rare cases where a const_cast is appropriate; it's also a typical one, namely making up for shortcomings with regards to const declarations in other code you have to use. If all functions in the MD5 class correctly declared their input parameters const, then no const_cast would be needed.
Also note that I just prepend every std identifier with std::, rather than having using namespace std. This is often the better, simpler, more consistent choice.
Now that we have our safe C++ mechanism in place, main becomes drastically simpler:
int main()
{
MD5 md5;
std::string result = SafeDigestString(md5, "Hello World");
std::cout << result << "\n";
}
We have laid the base to implement user input, which is best done with the std::getline function:
int main()
{
MD5 md5;
std::string input;
std::getline(std::cin, input);
std::string result = SafeDigestString(md5, input);
std::cout << result << "\n";
}
What is the most optimal way to achieve the same as this?
void foo(double floatValue, char* stringResult)
{
sprintf(stringResult, "%f", floatValue);
}
I'm sure someone will say boost::lexical_cast, so go for that if you're using boost, but it's basically the same as this anyway:
#include <sstream>
#include <string>
std::string doubleToString(double d)
{
std::ostringstream ss;
ss << d;
return ss.str();
}
Note that you could easily make this into a template that works on anything that can be stream-inserted (not just doubles).
http://www.cplusplus.com/reference/iostream/stringstream/
double d=123.456;
stringstream s;
s << d; // insert d into s
Boost::lexical_cast<>
On dinkumware STL, the stringstream is filled out by the C library snprintf.
Thus using snprintf formatting directly will be comparable with the STL formatting part.
But someone once told me that the whole is greater than or equal to the sum of its known parts.
As it will be platform dependent as to whether stringstream will do an allocation (and I am quite sure that DINKUMWARE DOES NOT YET include a small buffer in stringstream for conversions of single items like yours) it is truely doubtful that ANYTHING that requires an allocation (ESPECIALLY if MULTITHREADED) can compete with snprintf.
In fact (formatting+allocation) has a chance of being really terrible as an allocation and a release might well require 2 full read-modify-write cycles in a multithreaded environment unless the allocation implementation has a thread local small heap.
That being said, if I was truely concerned about performance, I would take the advice from some of the other comments above, change the interface to include a size and use snprintf - i.e.
bool
foo(const double d, char* const p, const size_t n){
use snprintf......
determine if it fit, etc etc etc.
}
If you want a std::string you are still better off using the above and instantiating the string from the resultant char* as there will be 2 allocations + 2 releases involved with the std::stringstream, std::string solution.
BTW I cannot tell if the "string" in the question is std::string or just generic ascii chars usage of "string"
The best thing to do would be to build a simple templatized function to convert any streamable type into a string. Here's the way I do it:
#include <sstream>
#include <string>
template <typename T>
const std::string to_string(const T& data)
{
std::ostringstream conv;
conv << data;
return conv.str();
}
If you want a const char* representation, simply substitute conv.str().c_str() in the above.
I'd probably go with what you suggested in your question, since there's no built-in ftoa() function and sprintf gives you control over the format. A google search for "ftoa asm" yields some possibly useful results, but I'm not sure you want to go that far.
I'd say sprintf is pretty much the optimal way. You may prefer snprintf over it, but it doesn't have much to do with performance.
Herb Sutter has done an extensive study on the alternatives for converting an int to a string, but I would think his arguments hold for a double as well.
He looks at the balances between safety, efficiency, code clarity and usability in templates.
Read it here: http://www.gotw.ca/publications/mill19.htm
_gcvt or _gcvt_s.
If you use the Qt4 frame work you could go :
double d = 5.5;
QString num = QString::number(d);
This is very useful thread. I use sprintf_s for it but I started to doubt if it is really faster than other ways. I came across following document on Boost website which shows performance comparison between Printf/scanf, StringStream and Boost.
Double to String is most common conversion we do in our code, so i'll stick with what i've been using. But, using Boost in other scenarios could be your deciding factor.
http://www.boost.org/doc/libs/1_58_0/doc/html/boost_lexical_cast/performance.html
In the future, you can use std::to_chars to write code like https://godbolt.org/z/cEO4Sd . Unfortunately, only VS2017 and VS2019 support part of this functionality...
#include <iostream>
#include <charconv>
#include <system_error>
#include <string_view>
#include <array>
int main()
{
std::array<char, 10> chars;
auto [parsed, error] = std::to_chars(
chars.data(),
chars.data() + chars.size(),
static_cast<double>(12345.234)
);
std::cout << std::string_view(chars.data(), parsed - chars.data());
}
For a lengthy discussion on MSVC details, see
https://www.reddit.com/r/cpp/comments/a2mpaj/how_to_use_the_newest_c_string_conversion/eazo82q/