How to create a CString from an array of chars? - c++

Need to log the content of buf using the LogMethod() below the problem is that
LogMethos only accepts a "Const CString&"
char buf[1024];
strcpy(buf, cErrorMsg);
// need to pass to LogMethod "buf" how do i do that?
log.LogMethod(const CString &);
Thans
Rev
Reversed

If you're talking about MFC CString, as far as I can tell, it should have a non-explicit constructor taking TCHAR const *. In other words, the following should work.
log.LogMethod(buf);
If it doesn't, please post the error message.

log.LogMethod(CString(buf));
This will avoid the problem where the compiler won't automatically create the CString object using the appropriate constructor since the argument is a reference (It would have if the argument was a "plain" CString).

CString cs;
cs = buf;
log.LogMethod(cs)

Related

Converting std::string to LPCSTR [duplicate]

As I clould not pass LPCSTR from one function to another (Data get changed) I tried passing it as a string.
But later I need to again convert it back to LPSTR. While trying the conversion I am getting the above error:
cannot convert from 'std::string' to 'LPSTR'
How can I resolve this?
That's just because you should use std::string::c_str() method.
But this involves const_cast in given case because const char * returned by c_str() can not be assigned to a non-constant LPSTR.
std::string str = "something";
LPSTR s = const_cast<char *>(str.c_str());
But you must be sure that lifetime of str will be longer that that of LPTSTR variable.
Another mention, if code compiles as Unicode-conformant, then types LPTSTR and std::string are incompatible. You should use std::wstring instead.
Important note: If you pass the resulting pointer s from above to a function which tries to modify the data it is pointing to this will result in undefined behaviour. The only way to properly deal with it is to duplicate the string into a non-const buffer (e.g. via strdup)
If you need an LPSTR, that means the string will/may be modified. std::string::c_str() returns a const pointer, and you can't just const_cast it away and hope all is good in the world, because it isn't. The string may be changed in all sorts of nasty ways, and your original std::string will be oblivious to all of them.
Try this instead:
// myFunction takes an LPSTR
std::string cppString = "something";
LPSTR cString = strdup( cppString.c_str() );
try {
myFunction( cString );
cppString = cString;
} catch(...) {
free( cString );
}
Wrap the string in a smart pointer and get rid of the try...catch for bonus points (don't forget the custom deleter).
There is a function on std::string c_str() . However I doubt that you could not use a std::string in your case.
Are you running somestringvariablename.c_str()?
That should work.
An LPSTR can be substituted with by using a TCHAR (i.e. found in tchar.h). So if you have a std::string, you can use the method std::string::c_str().
If the function, you are calling does not write to string, but only reads it, then you can simply use string::c_str method. If it is going to write something, then you probably should ensure that your string has enough space by calling string::reserve().

Convert std::string to char * alternative

I have done a search in google and been told this is impossible as I can only get a static char * from a string, so I am looking for an alternative.
Here is the situation:
I have a .txt file that contains a list of other .txt files and some numbers, this is done so the program can be added to without recompilation. I use an ifstream to read the filenames into a string.
The function that they are required for is expecting a char * not a string and apparently this conversion is impossible.
I have access to this function but it calls another function with the char * so I think im stuck using a char *.
Does anyone know of a work around or another way of doing this?
In C++, I’d always do the following if a non-const char* is needed:
std::vector<char> buffer(str.length() + 1, '\0');
std::copy(str.begin(), str.end(), buffer.begin());
char* cstr = &buffer[0];
The first line creates a modifiable copy of our string that is guaranteed to reside in a contiguous memory block. The second line gets a pointer to the beginning of this buffer. Notice that the vector is one element bigger than the string to accomodate a null termination.
You can get a const char* to the string using c_str:
std::string str = "foo bar" ;
const char *ptr = str.c_str() ;
If you need just a char* you have to make a copy, e.g. doing:
char *cpy = new char[str.size()+1] ;
strcpy(cpy, str.c_str());
As previous posters have mentioned if the called function does in fact modify the string then you will need to copy it. However for future reference if you are simply dealing with an old c-style function that takes a char* but doesn't actually modfiy the argument, you can const-cast the result of the c_str() call.
void oldFn(char *c) { // doesn't modify c }
std::string tStr("asdf");
oldFn(const_cast< char* >(tStr.c_str());
There is c_str(); if you need a C compatible version of a std::string. See http://www.cppreference.com/wiki/string/basic_string/c_str
It's not static though but const. If your other function requires char* (without const) you can either cast away the constness (WARNING! Make sure the function doesn't modify the string) or create a local copy as codebolt suggested. Don't forget to delete the copy afterwards!
Can't you just pass the string as such to your function that takes a char*:
func(&string[0]);

cannot convert from 'std::string' to 'LPSTR'

As I clould not pass LPCSTR from one function to another (Data get changed) I tried passing it as a string.
But later I need to again convert it back to LPSTR. While trying the conversion I am getting the above error:
cannot convert from 'std::string' to 'LPSTR'
How can I resolve this?
That's just because you should use std::string::c_str() method.
But this involves const_cast in given case because const char * returned by c_str() can not be assigned to a non-constant LPSTR.
std::string str = "something";
LPSTR s = const_cast<char *>(str.c_str());
But you must be sure that lifetime of str will be longer that that of LPTSTR variable.
Another mention, if code compiles as Unicode-conformant, then types LPTSTR and std::string are incompatible. You should use std::wstring instead.
Important note: If you pass the resulting pointer s from above to a function which tries to modify the data it is pointing to this will result in undefined behaviour. The only way to properly deal with it is to duplicate the string into a non-const buffer (e.g. via strdup)
If you need an LPSTR, that means the string will/may be modified. std::string::c_str() returns a const pointer, and you can't just const_cast it away and hope all is good in the world, because it isn't. The string may be changed in all sorts of nasty ways, and your original std::string will be oblivious to all of them.
Try this instead:
// myFunction takes an LPSTR
std::string cppString = "something";
LPSTR cString = strdup( cppString.c_str() );
try {
myFunction( cString );
cppString = cString;
} catch(...) {
free( cString );
}
Wrap the string in a smart pointer and get rid of the try...catch for bonus points (don't forget the custom deleter).
There is a function on std::string c_str() . However I doubt that you could not use a std::string in your case.
Are you running somestringvariablename.c_str()?
That should work.
An LPSTR can be substituted with by using a TCHAR (i.e. found in tchar.h). So if you have a std::string, you can use the method std::string::c_str().
If the function, you are calling does not write to string, but only reads it, then you can simply use string::c_str method. If it is going to write something, then you probably should ensure that your string has enough space by calling string::reserve().

CStringT to char[]

I'm trying to make changes to some legacy code. I need to fill a char[] ext with a file extension gotten using filename.Right(3). Problem is that I don't know how to convert from a CStringT to a char[].
There has to be a really easy solution that I'm just not realizing...
TIA.
If you have access to ATL, which I imagine you do if you're using CString, then you can look into the ATL conversion classes like CT2CA.
CString fileExt = _T ("txt");
CT2CA fileExtA (fileExt);
If a conversion needs to be performed (as when compiling for Unicode), then CT2CA allocates some internal memory and performs the conversion, destroying the memory in its destructor. If compiling for ANSI, no conversion needs to be performed, so it just hangs on to a pointer to the original string. It also provides an implicit conversion to const char * so you can use it like any C-style string.
This makes conversions really easy, with the caveat that if you need to hang on to the string after the CT2CA goes out of scope, then you need to copy the string into a buffer under your control (not just store a pointer to it). Otherwise, the CT2CA cleans up the converted buffer and you have a dangling reference.
Well you can always do this even in unicode
char str[4];
strcpy( str, CStringA( cString.Right( 3 ) ).GetString() );
If you know you AREN'T using unicode then you could just do
char str[4];
strcpy( str, cString.Right( 3 ).GetString() );
All the original code block does is transfer the last 3 characters into a non unicode string (CStringA, CStringW is definitely unicode and CStringT depends on whether the UNICODE define is set) and then gets the string as a simple char string.
First use CStringA to make sure you're getting char and not wchar_t. Then just cast it to (const char *) to get a pointer to the string, and use strcpy or something similar to copy to your destination.
If you're completely sure that you'll always be copying 3 characters, you could just do it the simple way.
ext[0] = filename[filename.Length()-3];
ext[1] = filename[filename.Length()-2];
ext[2] = filename[filename.Length()-1];
ext[3] = 0;
I believe this is what you are looking for:
CString theString( "This is a test" );
char* mychar = new char[theString.GetLength()+1];
_tcscpy(mychar, theString);
If I remember my old school MS C++.
You do not specify where is the CStringT type from. It could be anything, including your own implementation of string handling class. Assuming it is CStringT from MFC/ATL library available in Visual C++, you have a few options:
It's not been said if you compile with or without Unicode, so presenting using TCHAR not char:
CStringT
<
TCHAR,
StrTraitMFC
<
TCHAR,
ChTraitsCRT<TCHAR>
>
> file(TEXT("test.txt"));
TCHAR* file1 = new TCHAR[file.GetLength() + 1];
_tcscpy(file1, file);
If you use CStringT specialised for ANSI string, then
std::string file1(CStringA(file));
char const* pfile = file1.c_str(); // to copy to char[] buffer

C++ Variable Conversion

I need to pass one of my parameters to a write() function. It is asking for a type of 'const void*' I am a PHP guy and don't know C++ very well.
Here is my parameter:
const fmx::Text& distance = dataVect.AtAsText(3);
I don't know of any other way to pull in that field. I would love to just declare it const void* but I don't know how.
I guess just converting it would be easier than trying to pull it in the correct way??
The error message: cannot convert const fmx::Text to const void* for argument 2
write(fd, distance, 4);
I know this worked so can I just convert?
const void* s = "5000";
This is for a plugin in FileMaker so I don't really get c++ here.
Is there more anyone would need to help me solve this??
Thanks so much!
If fmx::Text was a pointer type, the compiler would automatically convert a reference to it into a void*. You need to use the address-of operator to give the function a pointer to work with:
write(fd, &distance, 4);
I don't really know filemaker, but this link shows that fmx::Text has a GetBytes function. You can then pass the pointer to the buffer filled with this function.
I'm assuming you actually want the text string.
I think you need to check the api for fmx::Text to get the string you want. Here is something I found to get the string out.
Looks like the type stores the data as UTF16, so you have to run a bit of code to get a string out, then pass it to your write function:
//a function to convert to a normal string
std::string getString(fmx::Text& Text)
{
char buffer[512] = {0}; //NOTE YOU HAVE A STRING SIZE LIMIT
// convert original text to ASCII text
outText.GetBytes( buffer, sizeof(buffer)-1, 0, Text.GetSize(), fmx::Text::kEncoding_Native );
return buffer;
}
Then call the function
std::string myString = getString(distance);
write(fd, myString.c_str(), myString.size());
Note I'm assuming a lot here...that you want a string in the current encoding, and not the raw UTF16 data from 'distance'. AND that GetBytes will not mangle the null characters in buffer....
You'll also need to include <string> in your c++ file.