How can i read data from my memory buffer?
const char *buf
and then print it out like this
MessageBoxA(NULL, "Buf: " + buf, " ", MB_OK);
std::string str = "Buf: ";
str += buf; // I assume buf is a null terminated string
MessageBoxA(NULL, str.c_str(), " ", MB_OK);
You can't apply + on string literals and/or char*. One of the operands has to be a std::string to be able to take advantage of std::string's operator+ overload.
If your buf is a char array, then something like this could work:
std::string("Buf: ") + buf
This requires that buf is null-terminated.
If buf isn't null-terminated however, Tony D's solution should work.
Related
1. I wrote the following code which compiles but crashes at run-time showing "Access violation writing" while calling _tcsset .
void function(TCHAR *tsatz)
{
printf( "Before: %s\n", tsatz );
_tcsset(tsatz,'*');
printf( "After: %s\n", tsatz );
}
void main( void )
{
TCHAR* tsatz;
tsatz = new char[256];
tsatz = "This is a test string ";
function(tsatz);
getchar();
}
Where am I wrong while using _tcsset ?
2. I know all the "safe" functions work if we tell them how big the target buffer is. But if i need to use _tcsset_s in "function" where tsatz is coming from external, is there a way?
I am a beginner. Any help i could get is greatly appreciated. Thanks in advance.
You are modifying a string literal, this is undefined behavior.
tsatz = "This is a test string ";
This will not copy the string literal into tsatz, it simply assigns tsatz to point to the address of "This is a test string ";, which cannot be modified.
One way around this is to declare tsatz as an array and initialize it with the string literal, which will automatically copy the text into the array for you
TCHAR tsatz[] = "This is a test string ";
If you need to keep track of the size of an array, you will either need to do so explicitly (note that sizeof an array will only work if the operand actually is an array, and not a pointer):
void function(TCHAR *tsatz, size_t numberOfElements)
{
_tprintf( "Before: %s\n", tsatz );
_tcsset_s(tsatz, numberOfElements, '*');
_tprintf( "After: %s\n", tsatz );
}
void main( void )
{
TCHAR tsatz[] = "This is a test string ";
function(tsatz, sizeof tsatz / sizeof(TCHAR));
getchar();
}
or use a template
template<size_t sz>
void function(TCHAR (tsatz&)[sz])
{
_tprintf( "Before: %s\n", tsatz );
_tcsset_s(tsatz, sizeof tsatz / sizeof(TCHAR), '*');
_tprintf( "After: %s\n", tsatz );
}
Or you could just use std::basic_string instead.
The problem with your code is that you assign a read-only C string to the pointer variable TCHAR* tsatz;; hence the access violation.
POSSIBLE SOLUTION:
TCHAR tsatz[256] = "This is a test string ";
function(tsatz);
"_tcsset()" and friends are non-portable; you're not likely to see them very often even in Windows-only code.
A much better solution, if possible for your application, would be to use C++ "std:string".
For example,
std::string tsatz = "This is a test string ";
std::fill(tsatz.begin(), tsatz.end(), '*');
I seem to be missing something in regards to converting a wostringstream to a LPCWSTR.
void counter_error(const wstring& input) {
wostringstream tempss;
tempss << L"Cannot find counter " << input;
LPCWSTR temp = tempss.str().c_str();
MessageBoxW(0, temp, L"ERROR", 0);
}
The "ERROR" caption shows up fine but the text below is garbled. I thought that it might be the c_str() function returning a regular char array instead of a wchar array but intellisense is telling me it returns a wchar array.
This line looks problematic:
LPCWSTR temp = tempss.str().c_str();
tempss.str() creates a temporary string which is destroyed at the end.
Try
void counter_error(const wstring& input) {
wostringstream tempss;
tempss << L"Cannot find counter " << input;
wstring temp_str = tempss.str();
LPCWSTR temp = temp_str.c_str();
MessageBoxW(0, temp, L"ERROR", 0);
}
Or, as #JoachimPileborg suggested, consider
MessageBoxW(0, (wstring(L"Cannot find counter " + input).c_str(), ...)
It still creates a temporary variable, but it is not going to be destroyed before returning from MessageBoxW.
So, I converted the string to byte in C++, but when it goes to add it into registry, it's stripping off the exe part but keeping the ., I have no idea what's wrong with it.
If you're wondering what NXS is, the value of it is "noerrorsplease.exe", type is char.
char szFinal[] = "";
strcat(szFinal, (const char *)ExtractDirectory(filepath).c_str());
//Not needed: strcat(szFinal, "");
strcat(szFinal, nxs);
strcat(szFinal, ".exe");
CString str;
str = szFinal;
str += ".exe";
cout << str.GetString() << endl;
const BYTE* pb = reinterpret_cast<const BYTE*>(str.GetString());
cout << pb << endl;
DWORD pathLenInBytes = *szFinal * sizeof(*szFinal);
if(RegSetValueEx(newValue, TEXT("Printing Device"), 0, REG_SZ, (LPBYTE)pb, pathLenInBytes) != ERROR_SUCCESS)
{
RegCloseKey(newValue);
cout << "error" << endl;
}
cout << "Possibly worked." << endl;
RegCloseKey(newValue);
This code
char szFinal[] = "";
strcat(szFinal, (const char *)ExtractDirectory(filepath).c_str());
is already invalid. You defined array szFina having only one character that is the terminating zero. You may not use it for copying in it any string. In these situations you should use an object of type std::string.
Hi i have the following code:
char msg[10000];
string mystr = "hello";
I want to put mystr into msg. Is there a way to do that? I tried all sorts of methods, but keep getting:
incompatible types in assignment of 'const char*' to char [10000]'
I tried:
msg = mystr.c_str();
and
msg = (char[10000])mystr;
to no avail.
You can try std::copy for this. Something like:
std::copy(mystr.begin(), mystr.end(), msg);
I would avoid C string functions like mempcy and strcpy in C++.
Take a look at string::copy - it takes a string an puts it into an array.
In your case it would be:
std::size_t length = mystr.copy(msg,10000);
msg[length]='\0';
char msg[10000];
string mystr = "hello";
strcpy(msg, mystr.c_str());
cout<<msg;
Use copy member function of std::string:
size_t len = mystr.copy(msg, (sizeof msg)-1);
msg[len] = 0;
String assignment in C is different. You have to copy the bytes into your destination string.
memcpy_s(msg, 1000, mystr.c_str(), mystr.length()) // safe windows version
memcpy(msg, mystr.c_str(), mystr.length()) // unix version
Use strcpy function :
http://www.cplusplus.com/reference/clibrary/cstring/strncpy/
strncpy(msg, mystr.c_str(), sizeof msg / sizeof msg[0]);
msg[sizeof msg / sizeof msg[0] - 1] = 0; // null-terminate in case of truncation
Compilers sometimes produce wonky error messages for array types.
Here's an accumulation of previous answers into a paste-and-compile program.
#include <string>
#include <iostream>
#if 1
int main(int argc, char **argv)
{
using std::cout;
using std::endl;
char msg[1000] = {0}; // initialize to 0 here since we're printing below
// the <type> <array-name>[<size>] = {0} just fills a POD struct or an array with 0s
std::string mystr = "hello";
// if, at some point, you have things changing "mystr"
// you'll need to make sure that it will fit in msg[]
cout << "Before strcpy: \"" << msg << "\"" << endl;
// I'll just finish the statement in mystr...
mystr += " world!";
if(mystr.length() < sizeof(msg)){
strcpy(
msg, // <- put in here until we find a '\0'
mystr.c_str() // <- take from here (which could be a temporary buffer)
);
}
//MSC will complain about strcpy being unsafe
//
// you can use the below instead (if you really feel the need to), which is
// the MS-specific equivalent to the above.
/*
strcpy_s(
msg, // <- put in here until we find a '\0' or the size limit is reached
sizeof(msg), // <- don't put any more than this many chars in msg
mystr.c_str() // <- take from here
);
*/
cout << "After strcpy: \"" << msg << "\"" << endl;
return 0;
}
#else
// Similarly, using wchar_t (a usually non-byte-sized character type)
//
// note where the divisions occurr
int main(int argc, char **argv)
{
using std::wcout;
using std::endl;
wchar_t msg[1000] = {0};
std::wstring mystr = L"hello";
wcout << "Before strcpy: \"" << msg << "\"" << endl;
mystr += L" world";
if(mystr.length() < (sizeof(msg)/sizeof(wchar_t))){
// mystr wil fit!
wcscpy(
msg, // <- put in here until we find a '\0'
mystr.c_str() // <- take from here (which could be a temporary buffer)
);
}
// Similar to the char case in the first preprocessor block
/*
wcscpy_s(
msg, // <- put in here until we find a '\0' or the size limit is reached
sizeof(msg)/sizeof(wchar_t), // <- don't put any more than this many wchar_ts in msg
mystr.c_str() // <- take from here
);
*/
wcout << "After strcpy: \"" << msg << "\"" << endl;
return 0;
}
#endif
I shall leave it to you to read the documentation on all related functions.
unsigned char *teta = ....;
...
printf("data at %p\n", teta); // prints 0xXXXXXXXX
How can I print variable address using iostreams? Is there a std::??? feature like std::hex to do this kind of conversion (address -> string), so std::cout << std::??? << teta << std::endl will print that address?
(no sprintf's, please ;))
Cast to void*:
unsigned char* teta = ....;
std::cout << "data at " << static_cast<void*>(teta) << "\n";
iostreams generally assume you have a string with any char* pointer, but a void* pointer is just that - an address (simplified), so the iostreams can't do anything other than transforming that address into a string, and not the content of that address.
Depending on wheter or not you want to use more formatting options printf gives, you could consider using sprintf
By it, you could format a string just like you'd do with printf, and afterwards print it out with std::cout
However, this would involve using a temporary char array so the choice depends.
An example:
unsigned char *teta = ....;
...
char formatted[ 256 ]; //Caution with the length, there is risk of a buffer overflow
sprintf( formatted, "data at %p\n", teta );
std::cout << formatted;