Related
I've tried to convert an integer to a hex null-terminated (or "C-style") string but I cannot use it with printf or my custom log function. It only works if I convert it to an std::string then use .c_str() when passing it as a parameter, which produces ugly, hard-to-understand code.
It's important to know that using std::string and appending to it with "str +=" does work.
const char* IntToHexString(int nDecimalNumber) {
int nTemp = 0;
char szHex[128] = { 0 };
char hex[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
while (nDecimalNumber > 0) {
nTemp = nDecimalNumber % 16;
sprintf(szHex, "%s%s", hex[nTemp], szHex);
nDecimalNumber = nDecimalNumber / 16;
}
sprintf(szHex, "0x%s", szHex);
return szHex;
}
I've tried to use Visual Studio Debugger but it doesn't show any error messages, because crashes somewhere in a DLL that has no symbols loaded
Your main problem is that you define a variable on the stack, locally in the function, and then return it.
After the function returns, the char* will point to "somewhere", to an undefined position. That is a major bug. You have also other bugs that have been commented on already. Like sprintf(szHex, "0x%s", szHex);, which is undefined behaviour (UB) or sprintf(szHex, "%s%s", hex[nTemp], szHex); which has the same problem + additionally a wrong format string.
The more C++ solution would be, as already shown in many posts:
#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
std::string toHexString(unsigned int hexValue)
{
std::ostringstream oss;
oss << "0x" << std::hex << hexValue;
return std::string(oss.str());
}
int main()
{
std::cout << toHexString(15) << '\n';
// or directly
std::cout << "0x" << std::hex << 15 << '\n';
return 0;
}
Of course a C-Style solution is also possible.
But all the following I would not recommend:
If you want to stick to C like solution with char *, you could make the char szHex[128] = { 0 }; static. Or, even better, pass in the pointer to a buffer and return its address, like in
#include <stdio.h>
#include <iostream>
char* toHexCharP(unsigned int hexValue, char *outBuffer, const size_t maxSizeOutBuffer)
{
snprintf(outBuffer,maxSizeOutBuffer-1,"0x%X",hexValue);
return outBuffer;
}
constexpr size_t MaxBufSize = 100U;
int main()
{
char buf[MaxBufSize];
std::cout << toHexCharP(15, buf, MaxBufSize) << '\n';
return 0;
}
But as said, I would not recomend. Too dangerous.
Your solution should look as follows:
std::string IntToHexString(int nDecimalNumber) {
std::ostringstream str;
str << std::hex << nDecimalNumber;
return str.str();
}
// ...
std::string transformed = IntToHexString(123);
You can then use transformed.c_str() to get your string as const char*.
Unless you have reasons to do so, you should never work with const char* in modern C++. Use std::string::c_str() if you need to.
I thought this would be really simple, but it's presenting some difficulties. If I have
std::string name = "John";
int age = 21;
How do I combine them to get a single string "John21"?
In alphabetical order:
std::string name = "John";
int age = 21;
std::string result;
// 1. with Boost
result = name + boost::lexical_cast<std::string>(age);
// 2. with C++11
result = name + std::to_string(age);
// 3. with FastFormat.Format
fastformat::fmt(result, "{0}{1}", name, age);
// 4. with FastFormat.Write
fastformat::write(result, name, age);
// 5. with the {fmt} library
result = fmt::format("{}{}", name, age);
// 6. with IOStreams
std::stringstream sstm;
sstm << name << age;
result = sstm.str();
// 7. with itoa
char numstr[21]; // enough to hold all numbers up to 64-bits
result = name + itoa(age, numstr, 10);
// 8. with sprintf
char numstr[21]; // enough to hold all numbers up to 64-bits
sprintf(numstr, "%d", age);
result = name + numstr;
// 9. with STLSoft's integer_to_string
char numstr[21]; // enough to hold all numbers up to 64-bits
result = name + stlsoft::integer_to_string(numstr, 21, age);
// 10. with STLSoft's winstl::int_to_string()
result = name + winstl::int_to_string(age);
// 11. With Poco NumberFormatter
result = name + Poco::NumberFormatter().format(age);
is safe, but slow; requires Boost (header-only); most/all platforms
is safe, requires C++11 (to_string() is already included in #include <string>)
is safe, and fast; requires FastFormat, which must be compiled; most/all platforms
(ditto)
is safe, and fast; requires the {fmt} library, which can either be compiled or used in a header-only mode; most/all platforms
safe, slow, and verbose; requires #include <sstream> (from standard C++)
is brittle (you must supply a large enough buffer), fast, and verbose; itoa() is a non-standard extension, and not guaranteed to be available for all platforms
is brittle (you must supply a large enough buffer), fast, and verbose; requires nothing (is standard C++); all platforms
is brittle (you must supply a large enough buffer), probably the fastest-possible conversion, verbose; requires STLSoft (header-only); most/all platforms
safe-ish (you don't use more than one int_to_string() call in a single statement), fast; requires STLSoft (header-only); Windows-only
is safe, but slow; requires Poco C++ ; most/all platforms
In C++11, you can use std::to_string, e.g.:
auto result = name + std::to_string( age );
If you have Boost, you can convert the integer to a string using boost::lexical_cast<std::string>(age).
Another way is to use stringstreams:
std::stringstream ss;
ss << age;
std::cout << name << ss.str() << std::endl;
A third approach would be to use sprintf or snprintf from the C library.
char buffer[128];
snprintf(buffer, sizeof(buffer), "%s%d", name.c_str(), age);
std::cout << buffer << std::endl;
Other posters suggested using itoa. This is NOT a standard function, so your code will not be portable if you use it. There are compilers that don't support it.
#include <iostream>
#include <sstream>
std::ostringstream o;
o << name << age;
std::cout << o.str();
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
string itos(int i) // convert int to string
{
stringstream s;
s << i;
return s.str();
}
Shamelessly stolen from http://www.research.att.com/~bs/bs_faq2.html.
This is the easiest way:
string s = name + std::to_string(age);
If you have C++11, you can use std::to_string.
Example:
std::string name = "John";
int age = 21;
name += std::to_string(age);
std::cout << name;
Output:
John21
It seems to me that the simplest answer is to use the sprintf function:
sprintf(outString,"%s%d",name,age);
#include <string>
#include <sstream>
using namespace std;
string concatenate(std::string const& name, int i)
{
stringstream s;
s << name << i;
return s.str();
}
#include <sstream>
template <class T>
inline std::string to_string (const T& t)
{
std::stringstream ss;
ss << t;
return ss.str();
}
Then your usage would look something like this
std::string szName = "John";
int numAge = 23;
szName += to_string<int>(numAge);
cout << szName << endl;
Googled [and tested :p ]
This problem can be done in many ways. I will show it in two ways:
Convert the number to string using to_string(i).
Using string streams.
Code:
#include <string>
#include <sstream>
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
int main() {
string name = "John";
int age = 21;
string answer1 = "";
// Method 1). string s1 = to_string(age).
string s1=to_string(age); // Know the integer get converted into string
// where as we know that concatenation can easily be done using '+' in C++
answer1 = name + s1;
cout << answer1 << endl;
// Method 2). Using string streams
ostringstream s2;
s2 << age;
string s3 = s2.str(); // The str() function will convert a number into a string
string answer2 = ""; // For concatenation of strings.
answer2 = name + s3;
cout << answer2 << endl;
return 0;
}
In C++20 you'll be able to do:
auto result = std::format("{}{}", name, age);
In the meantime you can use the {fmt} library, std::format is based on:
auto result = fmt::format("{}{}", name, age);
Disclaimer: I'm the author of the {fmt} library and C++20 std::format.
If you'd like to use + for concatenation of anything which has an output operator, you can provide a template version of operator+:
template <typename L, typename R> std::string operator+(L left, R right) {
std::ostringstream os;
os << left << right;
return os.str();
}
Then you can write your concatenations in a straightforward way:
std::string foo("the answer is ");
int i = 42;
std::string bar(foo + i);
std::cout << bar << std::endl;
Output:
the answer is 42
This isn't the most efficient way, but you don't need the most efficient way unless you're doing a lot of concatenation inside a loop.
If you are using MFC, you can use a CString
CString nameAge = "";
nameAge.Format("%s%d", "John", 21);
Managed C++ also has a
string formatter.
As a one liner: name += std::to_string(age);
The std::ostringstream is a good method, but sometimes this additional trick might get handy transforming the formatting to a one-liner:
#include <sstream>
#define MAKE_STRING(tokens) /****************/ \
static_cast<std::ostringstream&>( \
std::ostringstream().flush() << tokens \
).str() \
/**/
Now you can format strings like this:
int main() {
int i = 123;
std::string message = MAKE_STRING("i = " << i);
std::cout << message << std::endl; // prints: "i = 123"
}
As a Qt-related question was closed in favour of this one, here's how to do it using Qt:
QString string = QString("Some string %1 with an int somewhere").arg(someIntVariable);
string.append(someOtherIntVariable);
The string variable now has someIntVariable's value in place of %1 and someOtherIntVariable's value at the end.
There are more options possible to use to concatenate integer (or other numerric object) with string. It is Boost.Format
#include <boost/format.hpp>
#include <string>
int main()
{
using boost::format;
int age = 22;
std::string str_age = str(format("age is %1%") % age);
}
and Karma from Boost.Spirit (v2)
#include <boost/spirit/include/karma.hpp>
#include <iterator>
#include <string>
int main()
{
using namespace boost::spirit;
int age = 22;
std::string str_age("age is ");
std::back_insert_iterator<std::string> sink(str_age);
karma::generate(sink, int_, age);
return 0;
}
Boost.Spirit Karma claims to be one of the fastest option for integer to string conversion.
std::ostringstream
#include <sstream>
std::ostringstream s;
s << "John " << age;
std::string query(s.str());
std::to_string (C++11)
std::string query("John " + std::to_string(age));
boost::lexical_cast
#include <boost/lexical_cast.hpp>
std::string query("John " + boost::lexical_cast<std::string>(age));
Here is an implementation of how to append an int to a string using the parsing and formatting facets from the IOStreams library.
#include <iostream>
#include <locale>
#include <string>
template <class Facet>
struct erasable_facet : Facet
{
erasable_facet() : Facet(1) { }
~erasable_facet() { }
};
void append_int(std::string& s, int n)
{
erasable_facet<std::num_put<char,
std::back_insert_iterator<std::string>>> facet;
std::ios str(nullptr);
facet.put(std::back_inserter(s), str,
str.fill(), static_cast<unsigned long>(n));
}
int main()
{
std::string str = "ID: ";
int id = 123;
append_int(str, id);
std::cout << str; // ID: 123
}
Common Answer: itoa()
This is bad. itoa is non-standard, as pointed out here.
You can concatenate int to string by using the given below simple trick, but note that this only works when integer is of single digit. Otherwise, add integer digit by digit to that string.
string name = "John";
int age = 5;
char temp = 5 + '0';
name = name + temp;
cout << name << endl;
Output: John5
There is a function I wrote, which takes the int number as the parameter, and convert it to a string literal. This function is dependent on another function that converts a single digit to its char equivalent:
char intToChar(int num)
{
if (num < 10 && num >= 0)
{
return num + 48;
//48 is the number that we add to an integer number to have its character equivalent (see the unsigned ASCII table)
}
else
{
return '*';
}
}
string intToString(int num)
{
int digits = 0, process, single;
string numString;
process = num;
// The following process the number of digits in num
while (process != 0)
{
single = process % 10; // 'single' now holds the rightmost portion of the int
process = (process - single)/10;
// Take out the rightmost number of the int (it's a zero in this portion of the int), then divide it by 10
// The above combination eliminates the rightmost portion of the int
digits ++;
}
process = num;
// Fill the numString with '*' times digits
for (int i = 0; i < digits; i++)
{
numString += '*';
}
for (int i = digits-1; i >= 0; i--)
{
single = process % 10;
numString[i] = intToChar ( single);
process = (process - single) / 10;
}
return numString;
}
In C++ 20 you can have a variadic lambda that does concatenate arbitrary streamable types to a string in a few lines:
auto make_string=[os=std::ostringstream{}](auto&& ...p) mutable
{
(os << ... << std::forward<decltype(p)>(p) );
return std::move(os).str();
};
int main() {
std::cout << make_string("Hello world: ",4,2, " is ", 42.0);
}
see https://godbolt.org/z/dEe9h75eb
using move(os).str() guarantees that the ostringstream object's stringbuffer is empty next time the lambda is called.
You can use the C function itoa() like this:
char buf[3];
itoa(age, buf, 10);
name += buf;
I'm loosing my mind at the moment and below is what I'm trying to do.
char* buffer;
sprintf(buffer, "0x%08x", 5);
*(int *)(0x834AF2AC + 0x1a) = ?buffer?;
Buffer = 0x05000000
I need to set that in memory, if I just set 05 it will set 0x00000005
Question asked better.
How can I convert an INT into a format of "0x%08x"
So 5 becomes 0x05000000
ANSWERD:
The correct answer is *(int *)(0x834AF2AC + 0x1a) = 5<<24;
Something like this:
#include <iostream> // for std::cout, std::endl
#include <string> // for std::string, std::stoi
int main()
{
std::string s{"0x05"};
int i = std::stoi(s, nullptr, 16); // convert base 16 number in s to int
std::cout << i << std::endl;
}
Two result from google which points to stackoverflow (result 1 and 2).
Convert char to int in C and C++
C char* to int conversion
I'm not sure if I understand correctly but if you want to convert an entire string to int, then I would suggest stringstream.
http://www.cplusplus.com/reference/sstream/stringstream/stringstream/
For hexadecimal string:
#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::stringstream
int main () {
std::stringstream ss;
ss << std::hex << 0x05;
int foo;
ss >> foo;
std::cout << "foo: " << foo << '\n';
return 0;
}
I have the following:
char const* code = "3D";
I need to convert this 2-digit lexical hex into a std::string, which will be a string with length of 1 (not including null terminator). I have the boost library at my disposal as well. How can I do this?
In the example above, I should have a std::string that prints "=" if properly converted.
I think something on this order should work:
std::istringstream buffer("3D");
int x;
buffer >> std::hex >> x;
std::string result(1, (char)x);
std::cout << result; // should print "="
For example, using only standard C++03:
#include <cstdlib>
#include <string>
#include <iostream>
int main() {
char const* code = "3D";
std::string str(1, static_cast<char>(std::strtoul(code, 0, 16)));
std::cout << str << std::endl;
}
In a real application, you'd have to test whether the entire string has been converted (second argument to strtoul) and whether the conversion result is in the allowed range.
Here is a more elaborate example, using C++11 and Boost:
#include <string>
#include <cstddef>
#include <iostream>
#include <stdexcept>
#include <boost/numeric/conversion/cast.hpp>
template<typename T>
T parse_int(const std::string& str, int base) {
std::size_t index = 0;
unsigned long result = std::stoul(str, &index, base);
if (index != str.length()) throw std::invalid_argument("Invalid argument");
return boost::numeric_cast<T>(result);
}
int main() {
char const* code = "3D";
std::string str(1, parse_int<char>(code, 16));
std::cout << str << std::endl;
}
In Boost release 1.50 (coming this May), you would simply write
string s;
boost::algorithm::unhex ( code, std::back_inserter (s));
Works on std::string, std::wstring, QtString, CString, etc, etc.
It's not C++ but you can still use the good old scanf:
int d;
scanf("%x", &d);
Or from a string using sscanf:
int d;
sscanf(code, "%x", &d);
And using a std::string:
int d;
sscanf(code.c_str(), "%x", &d);
For some case the C format function (scanf & printf families) are easier to use than the object-oriented equivalent.
I need to store a double as a string. I know I can use printf if I wanted to display it, but I just want to store it in a string variable so that I can store it in a map later (as the value, not the key).
// The C way:
char buffer[32];
snprintf(buffer, sizeof(buffer), "%g", myDoubleVar);
// The C++03 way:
std::ostringstream sstream;
sstream << myDoubleVar;
std::string varAsString = sstream.str();
// The C++11 way:
std::string varAsString = std::to_string(myDoubleVar);
// The boost way:
std::string varAsString = boost::lexical_cast<std::string>(myDoubleVar);
The boost (tm) way:
std::string str = boost::lexical_cast<std::string>(dbl);
The Standard C++ way:
std::ostringstream strs;
strs << dbl;
std::string str = strs.str();
Note: Don't forget #include <sstream>
The Standard C++11 way (if you don't care about the output format):
#include <string>
auto str = std::to_string(42.5);
to_string is a new library function introduced in N1803 (r0), N1982 (r1) and N2408 (r2) "Simple Numeric Access". There are also the stod function to perform the reverse operation.
If you do want to have a different output format than "%f", use the snprintf or ostringstream methods as illustrated in other answers.
You can use std::to_string in C++11
double d = 3.0;
std::string str = std::to_string(d);
If you use C++, avoid sprintf. It's un-C++y and has several problems. Stringstreams are the method of choice, preferably encapsulated as in Boost.LexicalCast which can be done quite easily:
template <typename T>
std::string to_string(T const& value) {
stringstream sstr;
sstr << value;
return sstr.str();
}
Usage:
string s = to_string(42.5);
sprintf is okay, but in C++, the better, safer, and also slightly slower way of doing the conversion is with stringstream:
#include <sstream>
#include <string>
// In some function:
double d = 453.23;
std::ostringstream os;
os << d;
std::string str = os.str();
You can also use Boost.LexicalCast:
#include <boost/lexical_cast.hpp>
#include <string>
// In some function:
double d = 453.23;
std::string str = boost::lexical_cast<string>(d);
In both instances, str should be "453.23" afterward. LexicalCast has some advantages in that it ensures the transformation is complete. It uses stringstreams internally.
I would look at the C++ String Toolkit Libary. Just posted a similar answer elsewhere. I have found it very fast and reliable.
#include <strtk.hpp>
double pi = M_PI;
std::string pi_as_string = strtk::type_to_string<double>( pi );
The problem with lexical_cast is the inability to define precision. Normally if you are converting a double to a string, it is because you want to print it out. If the precision is too much or too little, it would affect your output.
You could also use stringstream.
Heh, I just wrote this (unrelated to this question):
string temp = "";
stringstream outStream;
double ratio = (currentImage->width*1.0f)/currentImage->height;
outStream << " R: " << ratio;
temp = outStream.str();
/* rest of the code */
Normaly for this operations you have to use the C default ecvt, fcvt or gcvt Functions:
/* gcvt example */
#include <stdio.h>
#include <stdlib.h>
main ()
{
char buffer [20];
gcvt (1365.249,6,buffer);
puts (buffer);
gcvt (1365.249,3,buffer);
puts (buffer);
return 0;
}
Output:
1365.25
1.37e+003
As a Function:
void double_to_char(double f,char * buffer){
gcvt(f,10,buffer);
}
You may want to read my prior posting on SO. (Macro'ed version with a temporary ostringstream object.)
For the record: In my own code, I favor snprintf(). With a char array on the local stack, it's not that inefficient. (Well, maybe if you exceeded the array size and looped to do it twice...)
(I've also wrapped it via vsnprintf(). But that costs me some type checking. Yelp if you want the code...)
Take a look at sprintf() and family.
Note that a string is just a representation of the double and converting it back to double may not result in the same value.
Also note that the default string conversion may trim the conversion to a certain precision.
In the standard C++ way, you can control the precision as follows:
#include <sstream>
#include <math.h>
#include <iostream>
#include <iomanip>
int main()
{
std::ostringstream sout;
sout << M_PI << '\n';
sout << std::setprecision(99) << M_PI << '\n';
sout << std::setprecision(3) << M_PI << '\n';
sout << std::fixed; //now the setprecision() value will look at the decimal part only.
sout << std::setprecision(3) << M_PI << '\n';
std::cout << sout.str();
}
which will give you the output
3.14159
3.141592653589793115997963468544185161590576171875
3.14
3.142
Use to_string().
example :
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string pi = "pi is " + to_string(3.1415926);
cout<< "pi = "<< pi << endl;
return 0;
}
run it yourself : http://ideone.com/7ejfaU
These are available as well :
string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);
You could try a more compact style:
std::string number_in_string;
double number_in_double;
std::ostringstream output;
number_in_string = (dynamic_cast< std::ostringstream*>(&(output << number_in_double <<
std::endl)))->str();
You can convert any thing to anything using this function:
template<class T = std::string, class U>
T to(U a) {
std::stringstream ss;
T ret;
ss << a;
ss >> ret;
return ret;
};
usage :
std::string str = to(2.5);
double d = to<double>("2.5");
C++17 has introduced:
std::to_chars, std::to_chars_result - cppreference.com
std::to_chars_result to_chars( char* first, char* last, float value,
std::chars_format fmt, int precision );
std::to_chars_result to_chars( char* first, char* last, double value,
std::chars_format fmt, int precision );
std::to_chars_result to_chars( char* first, char* last, long double value,
std::chars_format fmt, int precision );
Which provide fast low level way to convert floating points into string with some level of format control. This should be fast since no allocation is done, only custom implementation for specific scenario should be faster.
C++20 has introduced high level easy to use format string (equivalent of fmt library):
std::format - cppreference.com
std::format
template< class... Args >
std::string format( /*format_string<Args...>*/ fmt, Args&&... args );
template< class... Args >
std::wstring format( /*wformat_string<Args...>*/ fmt, Args&&... args );
template< class... Args >
std::string format( const std::locale& loc,
/*format_string<Args...>*/ fmt, Args&&... args );
template< class... Args >
std::wstring format( const std::locale& loc,
/*wformat_string<Args...>*/ fmt, Args&&... args );
Which is quite nice and handy. Should be faster then sprintf.