I am trying to use ifstream to read from a file.

When you use ifstream you have to specify the path like this.

ifstream Symb("Folder1\\Folder2\\File1.txt");

Instead of specifying like that, I will find a variable Text from a comboBox like
the code below.
Path has the string: "Folder1\\Folder2\\File1.txt"

When I try to put path into the parantheses of ifstream I have a lot of compiler errors.
Any idéas why this is happening ?

String^ Text;
Text = comboBox3->SelectedItem->ToString();

String^ Path = "C:\\Folder1\\Folder2\\" + Text + ".txt";
	
ifstream Symb(Path);

I think you need to use a cstring as an argument. The standard C++ thing would be to use the .c_str() method. I don't know what the equivalent is for this stuff.

I found this for you:

void MarshalString ( System::String* s, std::string& os )
{
   using namespace System::Runtime::InteropServices;
   const char* chars = 
      (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
   os = chars;
   Marshal::FreeHGlobal(IntPtr((void*)chars));
}

Is a C-style cast really the best option available?

Yes the .c_str() is used when you convert from std::string to String^

I will do the opposite way.
From String^ to std::string

I dont know how to do this ? If I have this string^ for example:

String^ str;

I think you need to use a cstring as an argument. The standard C++ thing would be to use the .c_str() method. I don't know what the equivalent is for this stuff.

void MarshalString( System::String* s, std::string& os )
{
   using namespace System::Runtime::InteropServices;
   const char* chars = 
      (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
   os = chars;
   Marshal::FreeHGlobal(IntPtr((void*)chars));
}

std::string path2;
MarshalString(Path, path2);
ifstream Symb(path2);

You should mention that you are using .NET when you post because it posses unique problems.

I thought it was C++/CLI.

That's what I mean. I don't have much experience with it but I can't say that I like managed c++ in .NET.

Yes I will tell I am using .NET.

Thank you for the code, though i dont really understand the logic. I have seen it before.
I have tried to put this code like this under a buttoncontrol but the compiler says:
MarshalString: Local function definitions illegal
'*' : cannot use this indirection on type 'System:: String'

I dont know If i am on the right track here:

String^ path;

void MarshalString ( System::String* s, std::string& os )
{   
        using namespace System::Runtime::InteropServices;   
        const char* chars = (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();   
        os = chars;   
        Marshal::FreeHGlobal(IntPtr((void*)chars));
}


	std::string path2;
	MarshalString(path, path2);
                ifstream Symb(path2);
void MarshalString( System::String* s, std::string& os )
{
   using namespace System::Runtime::InteropServices;
   const char* chars = 
      (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
   os = chars;
   Marshal::FreeHGlobal(IntPtr((void*)chars));
}

std::string path2;
MarshalString(Path, path2);
ifstream Symb(path2);

You should mention that you are using .NET when you post because it posses unique problems.

try:

void MarshalString ( System::String^ s, std::string& os )
...

Try it as a global function and just test it out. See if it works and then try to implement it in your code.

Is PtrToStringChars in the ballpark?

It's a possibility but you would then have to convert Char to char. :)

The code I posted really should work.

M'kay. My general rule of thumb has been, "if you 'need' a cast, there's a 95% chance you're doing it wrong".

Yes I tried this out to put all my other code away and a clean area only using this code:

void MarshalString ( System::String^ s, std::string& os )
{   
     using namespace System::Runtime::InteropServices;   
     const char* chars = (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();   
     os = chars;   
     Marshal::FreeHGlobal(IntPtr((void*)chars));
}

I changed from System:: String* s to System:: String ^

The only compiler error that I got now is:
error C2601: 'MarshalString' : local function definitions are illegal

I dont know what this meens really. I can find all the member like :: StringToHGlboalAnsi, ToPointer() and all others so they are in the library.

It's a possibility but you would then have to convert Char to char. :)

The code I posted really should work.

Post your entire code.

I solved it. It seemed that the code shouldn´t be inside a buttoncontrol, I didn´t know that, sorry, so I was putting this code in this area under public: Form3(void) etc... like this:

public:
Form3(void)
{
InitializeComponent();
     
}

     void MarshalString ( System::String^ s, std::string& os )
     {   
            using namespace System::Runtime::InteropServices;   
            const char* chars = (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();   
            os = chars;   
            Marshal::FreeHGlobal(IntPtr((void*)chars));
     }

So with this code in place I have put the code below inside my buttoncontrol.
If I only use the 2 first lines of this code Everything I have compile but when using the last line: ifstream Symb(path2); I will have compilerror:
cannot convert parameter 1 from 'std::string' to 'const char *

Anyway it seems that path2 is in the correct format anyway, std::string wich ifstream should take.

std::string path2;
MarshalString(path, path2);
ifstream Symb(path2);

Post your entire code.

ifstream Symb(path2.c_str());

Yes, this worked great. Now I have also learned how to convert like this.
Thank you very much for this help !

ifstream Symb(path2.c_str());

No problem. This is my way of procrastinating instead of doing things I should be getting done.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.