i have a pointer or variable which stores the address like 0xb72b218 now i have to store this value in to const char*. how i can store it. Thanks in advance.
I tried following:
suppose i have a pointer variable "ptr" which contains 0xb72b218 value
ostringstream oss;
oss << ptr;
string buf = oss.str();
const char* value = buf.c_str();
but it is more complicated any one know easy way.
Well... if you really want the address of something in a string, this will do:
#include <stdio.h>
#include <iostream>
int main(){
char buf[30];
void* ptr = /*your pointer here*/;
snprintf(buf,sizeof(buf),"%p",ptr);
std::cout << "pointer as string: " << buf << "\n";
std::cout << "pointer as value: " << ptr << "\n";
}
Or if you don't like magic numbers and want your code to work even when 256bit pointers are nothing special anymore, try this:
#include <limits> // for numeric_limits<T>
#include <stdint.h> // for intptr_t
#include <stdio.h> // for snprintf
#include <iostream>
int main(){
int i;
int* ptr = &i; // replace with your pointer
const int N = std::numeric_limits<intptr_t>::digits;
char buf[N+1]; // +1 for '\0' terminator
snprintf(buf,N,"%p",ptr);
std::cout << "pointer as string: " << buf << "\n";
std::cout << "pointer as value: " << static_cast<void*>(ptr) << "\n";
}
Example on Ideone.
OK, presumably there must some additional parameter that tells the function what type of data is actually being passed, but you can do it like this:
extern void afunc(const char *p, int type);
int value = 1234;
afunc((const char *)&value, TYPE_INT);
Have you looked at const_cast? It is a means of adding/removing const-ness from a variable in C++. Take a look here.
Related
How can I access individual elements in a std::string with pointers? Is it possible without type casting to a const char *?
#include <iostream>
#include <string>
using namespace std;
int main() {
// I'm trying to do this...
string str = "This is a string";
cout << str[2] << endl;
// ...but by doing this instead
string *p_str = &str;
cout << /* access 3rd element of str with p_str */ << endl;
return 0;
}
There are two ways:
Call the operator[] function explicitly:
std::cout << p_str->operator[](2) << '\n';
Or use the at function
std::cout << p_str->at(2) << '\n';
Both of these are almost equivalent.
Or dereference the pointer to get the object, and use normal indexing:
std::cout << (*p_str)[2] << '\n';
Either way, you need to dereference the pointer. Through the "arrow" operator -> or with the direct dereference operator * doesn't matter.
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.
Ran a simple program to test the pointer in string object, got
0x1875028
Hello
0x1875058 0x1875028
Hello world!!!
0x1875028
I am trying to understand why would s.c_str() change value after erase() call but not st.c_str().
Here is the simple code:
#include <vector>
#include <unordered_map>
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
string st;
void dum() {
string s("Hello world!!!");
printf("%p\n", s.c_str());
st = s;
s.erase(6);
cout << s << endl;
printf("%p %p\n", s.c_str(), st.c_str());
}
int main(int argc,char *argv[]) {
dum();
cout << st << endl;
st.erase(6);
printf("%p\n", st.c_str());
return 0;
}
This actually depends on the version you're using. See, for example Is std::string refcounted in GCC 4.x / C++11?. When you write for two strings, a, and b
a = b;
Then there's a question of whether they're internally pointing to the same object (up until one of them is modified). So either behavior your program exhibits is not very surprising.
First of all, I think this goes under the implementation details umbrella.
I tried that with VS2013.
After you call erase(), the string pointer returned by c_str() is not changed because I think the internal string implementation just updates the end of string (changing some internal data member), instead of doing a new heap reallocation for the internal string buffer (such an operation would likely return a new pointer value).
This is a behavior that I noted both for your local s string and the global st string.
Note that the STL implementation that comes with VS2013 doesn't use COW (COW seems to be non-standard C++11 compliant), so when you copy the strings with st = s, you are doing a deep copy, so the two strings are completely independent and they point to different memory buffers storing their respective string contents. So, when you erase something from one string, this operation is in no way reflected to the other copied string.
Sample Code
#include <iostream>
#include <string>
using namespace std;
// Helper function to print string's c_str() pointer using cout
inline const void * StringPtr(const string& str)
{
// We need a const void* to make cout print a pointer value;
// since const char* is interpreted as string.
//
// See for example:
// How to simulate printf's %p format when using std::cout?
// http://stackoverflow.com/q/5657123/1629821
//
return static_cast<const void *>(str.c_str());
}
string st;
void f() {
string s{"Hello world!!!"};
cout << "s.c_str() = " << StringPtr(s) << '\n';
st = s;
s.erase(6);
cout << s << '\n';
cout << "s.c_str() = " << StringPtr(s)
<< "; st.c_str() = " << StringPtr(st) << '\n';
}
int main() {
f();
cout << st << endl;
st.erase(6);
cout << "st.c_str() = " << StringPtr(st) << '\n';
}
Output
C:\Temp\CppTests>cl /EHsc /W4 /nologo test.cpp
test.cpp
C:\Temp\CppTests>test.exe
s.c_str() = 0036FE18
Hello
s.c_str() = 0036FE18; st.c_str() = 01009A40
Hello world!!!
st.c_str() = 01009A40
I was trying to execute the following code:
#include <iostream>
using namespace std;
int main()
{
int arr[4] = {1,2,3,4};
int *p;
p = arr;
cout << "p=" << p << endl;
char ch3[4] = {'c','d','e'};
char *ptr;
ptr = ch3;
cout << ptr << endl;
getchar();
return 0;
}
When I print the pointer p, it prints the address of the array 'arr' which is stored in it, whereas when I print the pointer ptr, it prints the array ch3 and not the address of it.
I wanted to know why is this happening.
Because operator<< is overloaded for const char* - that overload prints the char array located at that address.
To see the address itself, you'll need to cast it to void*:
cout<<static_cast<void*>(ptr)<<endl;
So, when I pass a const char * to a function once, can I use it again? It appears to end up spitting out crap to me.
const char *config_file = "file.txt";
function(int x, config_file);
cout << "Number" << x;
secondfunction(int y, config_file);
Do I need to make another pointer to config_file?
If so, how do I do that?
Thanks!
No, your can use it just fine. Despite the fact that the code you gave is uncompilable, I think I understand what you're asking.
A code segment like:
const char *x = "Hello";
fnA (x);
fnB (x);
should be just fine.
If you find that fnB is not getting what it expects then either:
fnA is changing what x points to (normally not possible since it's a const char *); or
some unshown piece of code is changing the pointer itself; or
something is corrupting the memory.
Try this code as an example:
#include <iostream>
#include <iomanip>
static void fnA (const char *a) {
std::cout << "fnA: [" << a << "]" << std::endl;
}
static void fnB (const char *b) {
std::cout << "fnB: [" << b << "]" << std::endl;
}
int main (void) {
const char *x = "Hello";
fnA (x);
fnB (x);
return 0;
}
It outputs, as expected:
fnA: [Hello]
fnB: [Hello]