This question already has answers here:
Converting double to char* in C++ with high performance
(9 answers)
Closed 7 years ago.
I am heavily struggling with a question which should be very easy: how do I do a simple type conversion (from double into char*) in basic C.
I have found quite some solutions, but they are all based on conversions from double to char[x], but I am working here with char*, not with char[]. (I don't know how long the resulting string will be).
On top of that, I really can't believe that another type (be it stringstream, std::strings, ...) are needed for something that simple.
I admit, I'm a complete newbie in basic C, but I have worked in other languages (Visual Basic, Delphi, Java, ...) and I just can't understand why I can't find a simple function like "to_char_pointer(double d)" to do this.
Does anybody have an idea?
You can use sprintf() as you have done to convert a double to a string, but I would actually recommend using _snprintf() instead simply because sprintf() has no regard for the fact that strings are fixed length devices in memory and will overflow if you don't watch it. _snprintf() allows you to specify the length of the out string, just be sure to specify the size as one less than the actual allocated memory block, because _snprintf() does not store the terminating null character if it has to cut the output short.
An example us using _snprintf() is:
void ToString(char * outStr, int length, double val)
{
_snprintf(outStr,length,"%f",val);
}
Related
This question already has answers here:
Multiplying a string by an int in C++
(10 answers)
Closed 2 years ago.
In Python, there is a way to multiply a string, for example, "A" * 3 would return "AAA". However, this syntax doesn't work in C++, it just gives me an error, invalid operands of types 'const char [2]' and 'int' to binary 'operator*'. Is there a way to multiply a string like this in C++?
There is no such operator in C++.
But you can write a function that takes a string and a number as argument, and return the repeated string.
std::string also has a constructor that repeats given character a number of times. This may be useful since you used a string of one character as the example.
You can overload an operator
std::string operator*(const std::string& s, unsigned n)
{
... // your code here
}
Not really... Although you can right one yourself. C++ is a very different beast to Python. It's much more low level and It is not as forgiving.
C++ deals with "real" memory (as it were).
You can't really just say "A" * 3 because before the "A" simply used 1 byte of memory if you have 3 "A"'s you need 3 bytes. and since C++'s main benefit is in it's ability to allow the user to author It's memory use, C++ won't just create 3 extra bytes.
You can implement your own version of Python's "A" * 3 by using the overload operator (although you would have to use a class type like string) C++ provides But I wouldn't really recommend this.
I'd suggest just using a std::vector and append the character as many times as you would like.
Also have a think about what you are trying to really do. C++ is all about performance rather than usability. If you are trying to set multiple bytes to a certain value you can use std::memset
This question already has answers here:
Turn off scientific notation on float
(2 answers)
Closed 2 years ago.
I'm currently coding a project for my Computer Science module but I'm having the problem of my string value defaulting to scientific notation if there are too many decimal places in the double value.
I've tried the obvious solution with ostringstream and .str() but it makes it into notation. I have to compile to the C++98 standard, so I cannot use modern solutions like std::to_string.
I need the value to be casted into a string but it needs to maintain its formatting. any help would be appreciated.
I would use:
std::to_string(myDouble);
If you use at least C++17, you could use std::to_chars() from #include <charconv>.
// `512` is here arbitrary, it is the max size of the output string.
// Smaller values should be sufficient.
char buffer[512];
// Here 'std::chars_format::fixed' tells the `std::to_chars()` to
// not use the scientific notation.
char* end = std::to_chars(std::begin(buffer), std::end(buffer), myDouble, std::chars_format::fixed).ptr;
// `end` the one-past-the-end pointer of the characters written to `buffer`.
This method is probably faster than the Emilien Lemaire's answer, however it's more verbose, and more error-prone. So this answer is only provided for completeness (as the performance gain may not worth it).
Moreover, unlike std::to_string(), the output string is locale-insensitive, so the double will always be formatted in the C locale (english locale).
This question already has answers here:
warning: format not a string literal and no format arguments
(3 answers)
Closed 8 years ago.
I've been trying to print a string literal but seems like I'm doing it wrong, since I'm getting a warning on compilation. It's probably due to wrong formatting or my misunderstanding of c_str() function, which I assume should return a string.
parser.y: In function ‘void setVal(int)’:
parser.y:617:41: warning: format not a string literal and no format arguments [-Wformat-security]
Line 617:
sprintf(temp, constStack.top().c_str());
Having those declarations
#include <stack>
const int LENGTH = 15;
char *temp = new char[LENGTH];
stack<string> constStack;
How can I provide a proper formating to string?
Simple - provide a format string:
sprintf(temp, "%s", constStack.top().c_str());
But much, much better:
string temp = constStack.top();
You are telling me in your comment that the problem is not so much the warning as the fact that your code doesn't do what you expect it to.
The solution to this and other, similar problems is to get rid of the strong C influence in your C++ code. Specifically, don't use raw dynamically allocated char arrays or sprintf. Use std::string instead.
In this case, you are using sprintf very incorrectly. Have you ever seen its signature? It goes like this:
sprintf(char *str, char const *format, ...)
str is the output of the operation. format describes what the output should be. The rest are the format arguments, which must by pure convention match what's described in format.
Now this "rest", written as ..., means that you can pass any number of arguments, even zero. And this is why your code even compiles (delivering a nice example for why ... is a dangerous feature, by the way).
In your code, the output string is, possibly incorrectly, your temp string. And the format to describe the output is, almost certainly incorrectly, what happens to sit on top of your stack.
Is this just about assigning one string to another, using sprintf simply because it more or less can do that as a very special case of what its feature set offers? There's no need for such hacks, as C++ has string assignment out of the box with std::string:
std::string temp = constStack.top();
Notice that this also eliminates the need to know the length of the string in advance.
If, for some reason, you really need formatting (but your question doesn't really show any need for it), then learn more about string streams as an alternative solution to format strings.
As the warning indicates it is issued as a result of the -Wformat-security option; you could simply disable the warning by removing the option; but it would be perhaps unwise.
The security issue is perhaps theoretical unless your code is to be widely distributed. Of perhaps more immediate concern is the possibility of your code crashing or behaving abnormally.
The problem is that the string is variable, and may at runtime contain formatting characters that cause it to attempt to read non-existent arguments. If for example the string is received from user input and the user entered "%s" it would attempt to read a string from some somewhere on the stack. That would at best place junk in temp, but worse if the memory read happened not to contain a nul character in the first 15 bytes, it would overrun temp, and corrupt the heap (in this case). Heap corruptions are probably worse than stack corruptions - the latent bug can remain unnoticed in your code for a long time only to start crashing after some unrelated change; and if it does crash, it is unlikely to be in any proximity to the cause.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm teaching my self WinAPI in c++, but as I progress I notice that every functions in WinAPI returns either char*, DWORD, LPCSTR and etc. My concern is I like using string, so what am I doing is after I get the return value I convert it to string. Is it good or bad? or does it make any difference if I convert it every time? or will it make the process slow or any bad stuffs. And for the I/O in c++, what is better cout or printf considering the size of exe or performance/functionality issue?
Start by learning the various string types. For example char*, LPSTR, and LPCSTR are all related and store ANSI characters; the last is a pointer to a const string. Similarly wchar_t*, WCHAR*, LPWSTR, and LPCWSTR are all related and store Unicode characters; again the last is a pointer to a const string.
Then watch what you mean when you say something like "returns char*" as most Windows APIs do nothing of the sort. Instead they take a LPSTR (a pointer to a char buffer) or LPWSTR (a pointer to a WCHAR buffer), and write into the buffer. Those APIs again almost always either take a count of characters available in the buffer, or have a documented buffer size requirement such as MAX_PATH.
You can use this to your advantage. C++11 requires that a std::wstring or std::string store its characters contiguously, and all known implementations did so well before that. So given an API like GetEnvironmentVariable, you can use the string as the buffer directly and sidestep most conversions. Use code similar to this, but feel free to modify how it interacts with the rest of your code:
std::wstring GetEnvironmentVariable(const std::wstring& strName)
{
DWORD cchValue = MAX_PATH;
std::wstring strValue;
// call API once or twice, to get required buffer size
strValue.resize(cchValue);
cchValue = GetEnvironmentVariable(strName.c_str(), &strValue[0], cchValue);
if (cchValue > MAX_PATH)
{
strValue.resize(cchValue);
cchValue = GetEnvironmentVariable(strName.c_str(), &strValue[0], cchValue);
}
// process errors such as ERROR_ENVVAR_NOT_FOUND
if (0 == cchValue)
{
// throw exception? return empty string? (current code does latter)
}
// remove null character and any extra buffer
strValue.resize(cchValue);
return strValue;
}
There are a lot of further enhancements you can make to this approach.
If you need to support old Windows 9x era operating systems, you can use LPTSTR instead by creating a typedef tstring that maps to std::wstring or std::string per the definition of UNICODE (otherwise I'd suggest just doing wide strings like I showed above). You can do explicit A and W function calls that either overload in C++, or follow the Windows naming convention.
You might be able to refactor the double call into some helper, or at least factor out some of the steps it requires.
You can handle APIs that take an in-out parameter for the buffer size.
You can figure out a way to handle APIs such as GetWindowText that only return a success/failure but do not return their required buffer size, and hide that dance behind your new wrapper function. See the related question and answer for an example approach. (Also note that other approaches may be better for that specific case.)
As far as I/O, there isn't a clear winner. You'll find that it's fairly rare to use the console and console I/O in Windows, so perhaps the question isn't very interesting after all. Aside from that, there are significant tradeoffs when it comes to internationalization; namely it's a lot easier to translate full sentence format strings than to translate the fragments that tend to result from uses of iostream. But if translation isn't a concern for you, that won't influence your decision.
Nearly everything you asked is opinion based. Yes, converting every char* you get to an std::string will be slower, but no it won't make much of a difference. Of course that is completely up to how often you're doing that, and where you'll be running this program. There's absolutely no problem with converting things to std::string in this case, but be warned, you're not going to have a fun time fighting against any API( it's going to be a lot more tedious to convert to and from types all the time. ) In the end, it's completely up to you. Just remember, just because you converted a char* that you allocated with new or malloc into an std::string doesn't mean you don't have to free, or delete it.
I don't see a problem with either printf or std::cout. Once again that's completely opinion based. However, std::cout might be a little easier to use and is certainly more type-safe.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C++ char* vs std::string
I'm new to C++ coming from C# but I really do like C++ much better.
I have an abstract class that defines two constant strings (not static). And I wondered if a const char* would be a better choice. I'm still getting the hang of the C++ standards, but I just figured that there really isn't any reason why I would need to use std::string in this particular case (no appending or editing the string, just writing to the console via printf).
Should I stick to std::string in every case?
Should I stick to std::string in every case?
Yes.
Except perhaps for a few edge cases where you writing a high performance multi-threaded logging lib and you really need to know when a memory allocation is going to take place, or perhaps in fiddling with individual bits in a packet header in some low level protocol/driver.
The problem is that you start with a simple char and then you need to print it, so you use printf(), then perhaps a sprintf() to parse it because std::stream would be a pain for just one int to string. And you end up with an unsafe and unmaintainable mix oc c/c++
I would stick to using std::string instead of const char*, simply because most of the built-in C++ libraries work with strings and not character arrays. std::string has a lot of built-in methods and facilities that give the programmer a lot of power when manipulating strings.
Should I stick to std::string in every case?
There are cases where std::string isn't needed and just a plain char const* will do. However you do get other functionality besides manipulation, you also get to do comparison with other strings and char arrays, and all the standard algorithms to operate on them.
I would say go with std::string by default (for members and variables), and then only change if you happen to see that is the cause of a performance drop (which it won't).
Use std::string when you need to store a value.
Use const char * when you want maximum flexibility, as almost everything can be easily converted to or from one.
This like comparing Apples to Oranges. std::string is a container class while char* is just a pointer to a character sequence.
It really all depends on what you want to do with the string.
Std::string on the other hand can give you a quick access for simple string calculation and manipulation function. Most of those are simple string manipulation functions, nothing fancy really.
So it basically depends on your needs and how your functions are declared. The only advantage for std::string over a char pointer is that it doesnt require a specific lenghth decleration.