convert std::string to nsstring issue - c++

Hi
I use the following to convert std::string to NSString but it return (null) while trying to display the value of the nsstring
I need it to return instead of (null) empty at conversion time any suggestion
StudyDate=[NSString stringWithCString:studyDate length:strlen(studyDate)];
any suggestion to avoid null values
best regards

Edit: The syntax #"string" is used only for constructing NSString. With std::string you should use the standard "string" syntax.
NSString* aConstantNSString = #"foo";
const char* aConstantCString = "foo";
std::string aConstantStdString = "foo";
CFStringRef aConstantCFString = CFSTR("foo");
+stringWithCString:length: has been deprecated since the very early beginning of the iPhone SDK. If the string contains only ASCII characters, often you could use +stringWithUTF8String: instead.
Your method works only when studyDate is a C string (i.e. const char*), but you said you have a std::string. There is no method to directly convert a std::string into an NSString. You must use .c_str() to create the C string first:
StudyDate = [NSString stringWithUTF8String:studyDate.c_str()];
(But the above shouldn't be the cause you're getting (null) because passing a std::string to +stringWithCString:length: or even strlen should give a compile-time error immediately.
'error: cannot convert ‘std::string’ to ‘const char*’ in argument passing'
So studyDate should already be a const char*. We need more context (code) to see what's going on.)

NSString objCString = #"this is my objective c string";
std::string cppString; // this is your c++ string or however you declared it blah blah blah
cppString = [objCString UTF8String];
// this is the conversion of an NSString into a c++ string
// not sure if it will work for c strings but you can certainly try
thats all there is too it im afraid. all you need is just that one line of code. this was done in ios sdk 4.3 btw so im not sure if the coding will change if you appiled it elsewhere.

Related

conversion between char* and std::string and const char*

I am now using C++ to program a robot using PROS. Pros has a print function, which is taking in a const char*. Now, I'm using lvgl to create my own screen, and I want to replicate the print function. Like the printf() functions, I want it to include variadic params to do the %d effect (so it converts all the %? to the corresponding values). The problem now is about the conversions between functions. I wanted to make a convert function to convert a string and the variadic params into a complete string. I need to input is a string which is like "hey" and I'm unsure what the type name should be. I need to be able to get size, search in it for %ds but I need the function to return a const char* to pass onto the lvgl to pring on the screen. I am having a bad time trying to convert a string into an const char* for the out put of the convert function.
Also, I tried using the input type as a char*, and when I input a string like "hello" is says a error [ISO C++11 does not allow conversion from string literal to 'char ' [-Wwritable-strings]]. But instead, when is use a const char, the error disappears. Anyone knows why?
Thanks everyone for your kind help!
char* and const char* are two flavours of the same thing: C-style strings. These are a series of bytes with a NUL terminator (0-byte). To use these you need to use the C library functions like strdup, strlen and so on. These must be used very carefully as missing out on the terminator, which is all too easy to do by accident, can result in huge problems in the form of buffer-overflow bugs.
std::string is how strings are represented in C++. They're a lot more capable, they can support "wide" characters, or variable length character sets like UTF-8. As there's no NUL terminator in these, they can't be overflowed and are really quite safe to use. Memory allocation is handled by the Standard Library without you having to pay much attention to it.
You can convert back and forth as necessary, but it's usually best to stick to std::string inside of C++ as much as you can.
To convert from C++ to C:
std::string cppstring("test");
const char* c_string = cppstring.c_str();
To convert from C to C++:
const char* c_string = "test";
std::string cppstring(c_string);
Note you can convert from char* (mutable) to const char* (immutable) but not in reverse. Sometimes things are flagged const because you're not allowed to change them, or that changing them would cause huge problems.
You don't really have to "convert" though, you just use char* as you would const char*.
std::string A = "hello"; //< assignment from char* to string
const char* const B = A.c_str(); //< call c_str() method to access the C string
std::string C = B; //< assignment works just fine (with allocation though!)
printf("%s", C.c_str()); //< pass to printf via %s & c_str() method

Conversion (const char*) var goes wrong

I need to convert from CString to double in Embedded Visual C++, which supports only old style C++. I am using the following code
CString str = "4.5";
double var = atof( (const char*) (LPCTSTR) str )
and resutlt is var=4.0, so I am loosing decimal digits.
I have made another test
LPCTSTR str = "4.5";
const char* var = (const char*) str
and result again var=4.0
Can anyone help me to get a correct result?
The issue here is, that you are lying to the compiler, and the compiler trusts you. Using Embedded Visual C++ I'm going to assume, that you are targeting Windows CE. Windows CE exposes a Unicode API surface only, so your project is very likely set to use Unicode (UTF-16 LE encoding).
In that case, CString expands to CStringW, which stores code units as wchar_t. When doing (const char*) (LPCTSTR) str you are then casting from a wchar_t const* to a char const*. Given the input, the first byte has the value 52 (the ASCII encoding for the character 4). The second byte has the value 0. That is interpreted as the terminator of the C-style string. In other words, you are passing the string "4" to your call to atof. Naturally, you'll get the value 4.0 as the result.
To fix the code, use something like the following:
CStringW str = L"4.5";
double var = _wtof( str.GetString() );
_wtof is a Microsoft-specific extension to its CRT.
Note two things in particular:
The code uses a CString variant with explicit character encoding (CStringW). Always be explicit about your string types. This helps read your code and catch bugs before they happen (although all those C-style casts in the original code defeats that entirely).
The code calls the CString::GetString member to retrieve a pointer to the immutable buffer. This, too, makes the code easier to read, by not using what looks to be a C-style cast (but is an operator instead).
Also consider defining the _CSTRING_DISABLE_NARROW_WIDE_CONVERSION macro to prevent inadvertent character set conversions from happening (e.g. CString str = "4.5";). This, too, helps you catch bugs early (unless you defeat that with C-style casts as well).
CString is not const char* To convert a TCHAR CString to ASCII, use the CT2A macro - this will also allow you to convert the string to UTF8 (or any other Windows code page):
// Convert using the local code page
CString str(_T("Hello, world!"));
CT2A ascii(str);
TRACE(_T("ASCII: %S\n"), ascii.m_psz);
// Convert to UTF8
CString str(_T("Some Unicode goodness"));
CT2A ascii(str, CP_UTF8);
TRACE(_T("UTF8: %S\n"), ascii.m_psz);
Found a solution using scanf
CString str="4.5"
double var=0.0;
_stscanf( str, _T("%lf"), &var );
This gives a correct result var=4.5
Thanks everyone for comments and help.

Opening directory function

This is a basic understanding concepts related question.
Working using: Embarcadero C++ Builder
What is the difference between:
opendir("C:\\XYZ")
and
String file = "C:\\XYZ";
opendir(file);
Aren't both strings?
The first one works but the sexond gives me error:
E2034 Cannot convert Unicode String to ' const char*'
In a case where I take input from the user I can only pass a string. How do i pass the whole path?
first one is a const char*, second one is a std::string. The opendir function accepts only const char* in your case and thus cannot convert std::string to const char* on its own. you can get the function to work by opendir(file.c_str()); .
No. A String is not a char array. opendir needs a char array.
opendir() expects an 8bit narrow const char* as input. When you pass a narrow literal to opendir(), you are passing it a const char[], which implicitly degrades to const char*, and all is fine.
String is System::String, which is a typedef for System::UnicodeString, which is Embarcadero's UTF-16 encoded string class (similar to std::wstring, but with different semantics). When you pass a String to opendir(), you get a conversion error.
To pass a String value to opendir() (or any other function that expects char*), you need to first convert it to a System::AnsiString, and then use AnsiString::c_str() to get a char* from it, eg:
String file = "C:\\XYZ";
opendir(AnsiString(file).c_str());

C++ converting string to char is not working

I have the following code to convert a string to char :
string tempLine = dataLine[studentIndex];
char str = tempLine.c_str();
but this line returns an error : " a value of type "constant char *" cannot be used to initialize an entity of type "char".
How can I fix this issue??
should be:
const char *str = tempLine.c_str();
Note that you're not supposed to change the content of the string. Generally, its not a good way to work with C++ strings. If you really have to fully convert a C++ string to C string - allocate memory and use strcpy to copy data, don't use the C++ string buffers directly.
edit for your request in the comments: Look here for C++ learning resources.
You cannot convert a const char*, which is what std::string::c_str() returns, to char. Change:
char str = tempLine.c_str();
to:
const char* str = tempLine.c_str();
Note this does not copy the characters in tempLine to str, str just refers to the characters in tempLine.

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