How LoadString() works in VC++? - c++

I am working on an MFC application where when I write Something like this:CString sName; sName.LoadString(IDS_NAME_STRING) it works fine but when I try to write while initializing in one line like CString sName = sName.LoadString(IDS_NAME_STRING), I am getting error
Error C2440 'initializing': cannot convert from 'BOOL' to 'ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<_CharType>>>'
I am not getting what's wrong with the latter statement. Can anyone help me to understand this error?

CString::LoadString returns a value of type BOOL. That's what the error message is telling you. It turned out to be a bit longer as it includes the full template instantiations. It's ultimately saying
cannot convert from 'BOOL' to 'CString'
The solution is what you already have:
CString sName;
sName.LoadString(IDS_NAME_STRING);
If you'd rather have that as a single statement, you'll have to implement a function for it, e.g.
CString load_string(uint32_t id) {
CString s;
s.LoadString(id);
return s;
}
With that you can write
auto s = load_string(IDS_NAME_STRING);
Note that the function load_string mirrors the behavior of the initial code: If a string resource with any given ID cannot be found, it returns an empty string. If you'd rather have failure communicated to clients you could throw an exception.

Related

ofstream returning error "No matching function to call std::basic_ofstream<char>::close(const char [14])"

Need help fixing my code, not sure what's wrong. I'm using C++11, trying to write a vector to a file by individually writing each struct. The section of code returning an error is:
string craigSave = "craigSave.txt";
ofstream file(craigSave.c_str());
file.open("craigSave.txt");
for (int i=0; i<finalVector.size(); i++){
file << finalVector[i]<<endl;
}
file.close("craigSave.txt");
cout<<"Thanks for shopping!"<<endl;
done = true;
The error returned is on the "file.close" line and is:
error: no matching function for call to 'std::basic_ofstream::close(const char [14])'
I research on this error seems to point to needing to use char* as an argument instead of a string, but I'm using C++11, so it should accept strings. Also it is strange that there is no error for the file.open line, as all research shows the error being there, not at file.close
Just use file.close();, there's no need to pass the file name again.
See http://www.cplusplus.com/reference/fstream/ofstream/close/.
Also, ofstreams are RAII objects, which means that the file will automatically be closed once the ofstream object goes out of scope (see do I need to close a std::fstream?):
{
ofstream out("name");
// do something with out...
} // out.close is called automatically

No viable conversion from 'bool' to 'std::string'

I have some code that looks like this:
static std::string Foo(const std::string& blah)
{
if ( someWierdEdgeCase() ){
return false; // <-- this line has a compiler error
}
std::string resourcePath;
resourcePath.append("/assets/");
return resourcePath;
}
It used to compile fine, but then I upgraded to Xcode 5.1, and now it no longer compiles. The error I get is the following one:
No viable conversion from 'bool' to 'std::string'
I would like to know what I should replace 'return false' with so that this works the way it used to.
Normally, I would be happy to return something other than false, and clearly that is not good behavior. But somehow this code used to compile and run, and I want to understand what it was doing, in case some other part of this codebase is relying on what is certainly weird behavior.
This:
return false; // <-- this line has a compiler error
There is no standard way to convert bool to std::string (please correct me if there is or was something special in gcc (the old XCode mac compiler)). This means that your code base used to contain explicit code to convert the bool to string.
If it is not compiling now this suggests this conversion was removed from your code base.
A couple of people of suggested alternatives. But I doubt any of these are going to work. As the old code had a depedency on how it used to work. So making any specific recomendation will depend on working out how the old code compiled and what it returned when someWierdEdgeCase() is true. Basically you need to replicate this behavior.
Otherwise you need to hunt down all used cases in your code and change the behavior to match the new behavior. In this case I would change the name of the function. Re-Compile and see where the code breaks and check the behavior at each location and make sure it behaves the same.
static std::string Foo(const std::string& blah)
{
std::string resourcePath = "";
if ( someWierdEdgeCase() ){
return resourcePath; // <-- Now you're returning a string
}
resourcePath.append("/assets/");
return resourcePath;
}
If you need the return type to be - for whatever reason - not always present, return by pointer, instead of returning by value.
static yourType* Foo(const std::string& blah){
if ( someWierdEdgeCase() ){
return 0;
}
}
Then you can test and assign the function in the same line
yourType* result;
if(result = Foo("something")){
// the result was correct
Of course - since your function returns a std::string, you can return an empty string (""), or - also independent of the return type - throw an exception.
I had same issue that with the fact that my interface file and implementation file were using different data types in method declaration.Putting same data type on both place in method declaration error went away.

Error when passing a 'system::string' to a function

I have the following function, which will hopefully tell me whether or not a folder exists, but when I call it, I get this error -
cannot convert parameter 1 from 'System::String ^' to 'std::string'
The function -
#include <sys/stat.h>
#include <string>
bool directory_exists(std::string path){
struct stat fileinfo;
return !stat(path.c_str(), &fileinfo);
}
The call (from the form.h file that holds the form where the user selects the folder) -
private:
System::Void radioListFiles_CheckedChanged(System::Object^ sender, System::EventArgs^ e) {
if(directory_exists(txtActionFolder->Text)){
this->btnFinish->Enabled = true;
}
}
Is anyone able to tell me how to filx this? Thanks.
You're trying to convert from a managed, C++/CLI string (System::String^) into a std::string. There is no implicit conversion provided for this.
In order for this to work, you'll have to handle the string conversion yourself.
This will likely look something like:
std::string path = context->marshal_as<std::string>(txtActionFolder->Text));
if(directory_exists(path)) {
this->btnFinish->Enabled = true;
}
That being said, in this case, it might be easier to stick to managed APIs entirely:
if(System::IO::Directory::Exists(txtActionFolder->Text)) {
this->btnFinish->Enabled = true;
}
You are trying to convert a CLR string to a STL string to convert it to a C-string to use it with a POSIX-emulation function. Why such a complication? Since you are using C++/CLI anyway, just use System::IO::Directory::Exists.
To make this work you need to convert from the managed type System::String to the native type std::string. This involves a bit of marshaling and will result in 2 separate string instances. MSDN has a handy table for all of the different types of marshaling for strings
http://msdn.microsoft.com/en-us/library/bb384865.aspx
In this particular case you can do the following
std::string nativeStr = msclr::interop::marshal_as<std::string>(managedStr);

How to use UTF8Encoding in Visual C++

I need to change the below c# code to c++ code.
public static byte[] StrToByteArray(string str)
{
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
return encoding.GetBytes(str);
}
on this website i found the c++ code for UTF8Encoding from which i created this code
void StrToByteArray(string unicodeString)
{
UTF8Encoding^ utf8 = gcnew UTF8Encoding;
array<Byte>^encodedBytes = utf8->GetBytes( unicodeString );
}
but this gives me the following error
Error 2 error C2664: 'cli::array
^System::Text::Encoding::GetBytes(cli::array
^)' : cannot convert parameter 1 from
'std::string' to
'cli::array
Why would it do this while it is identical to the documentation? (except i am using a normal string, but using a top level string^ gives me an error on that.)
i'm not sure if it is related but my code is managed.
note: i tried not worrying yet about returning any data till i get this working.
string is a different data type in C++ as it is in C#. Try using System::String^ instead.

regarding encryption method

i am using encrypt function of cryptography api(fun declared as virtual)
//fun declaration
TBool EncryptL(const TDesC8 &aInput, TDes8 &aOutput);
//function calling
TBuf8<10> text;
TBuf8<10> cipher;
text.Copy(_L("Hello"));
iEncryptor.EncryptL(text,cipher); it shows error expression syntax error
//fun definition
TBool CRSAAlgo::EncryptL(const TDesC8 &aInput,TDes8 &aOutput)
{
if(iEncryptor)
{
TInt len = iEncryptor->MaxInputLength();
}
}
i want to know what is exact problem
The main issue here, the reason your compiler complains is that you are using iEncryptor as an object or a reference, while it probably is a C++ pointer.
To move to the next stage, try using:
iEncryptor->EncryptL(text,cipher);
As you did not post the exact error message you get from the compiler I have to guess.
I assume the problem is that the EncryptL function you show expects to get arguments of type TDesC8 and you pass a TBuf8<10> to it. Unless TDesC8 were a typedef to TBuf8<10> these are different and therefore for the compiler incompatible types.
Ypou are also using iEncryptor once as a pointer: iEncryptor->MaxInputLength(); and at the location where you see the error as an object: iEncryptor.EncryptL(text,cipher);. Only one form can be correct. As we don't have more code from you I don't know which, but given the fact that the latter has the error I suspect the latter.