Sign in to follow this  
originaldaemon

Converting string types

Recommended Posts

I have created these two functions in a console programme: struct Info{ char firstname[20]; char lastname[20]; }temp; void addInfo{ fstream file; file.open("info.txt", ios::in|ios::end); cin.getline(temp.firstname, '100'); cin.getline(temp.lastname, '100'); file.write((char *)&temp, sizeof(Info)); file.close(); } void viewInfo{ fstream file; file.open("info.txt", ios::in|ios::beg); do{ file.read((char *)&temp, sizeof(Info)); cout<<temp.firstname<<endl; cout<<temp.lastname<<endl; cout<<"--------"<<endl; while(!file.eof()); } Now i want to put them into a windows form. So far i have made it so the form can open the file specified by the user. I use this function to convert from the system string to a char pointer: char *strPointer = (char *)Marshal::StringToHGobalAnsi(textBox->text).toPointer(); then i can use: fstream::open(strPointer, ios::in| ios::out| ios::beg) to open the file. My problem is i can't read or write information to the file because i can't convert between char *, char array and system::string (im using char arrays to store the information because i havn't been able to get it to work with std::Strings or system::strings). If someone can tell me how to convert between these data types or a way to use other information types in the struct that would be very helpful. P.S. i do have access to a lot of c++ books but none of them tell you anything about windows forms and all the examples of the fstream they use only deal with char arrays. When i say a lot i am talking about a good 20 books. Can someone point me in the direction of a book that does deal with these issues, the more detail the better because im also finding a lot of them very vague. [Edited by - originaldaemon on July 29, 2008 10:42:22 AM]

Share this post


Link to post
Share on other sites
The simple solution for the std::string is that when you need to 'use' the string, where you would normally use a char array, you call its c_str() function.

fstream::open(temp.firstname.c_str(), ios::in| ios::out);

std::strings are not null terminated, which is what something expecting a char array wants. c_str() returns a null terminated copy of the string.

Share this post


Link to post
Share on other sites
The problem with std::strings was when i was using the fstream read and write. I couldn't write out the struct of strings. I tried:

write((char *)temp.firstname.c_str(), sizeof(temp.name))

but when i read the string from the file all i got was jargen. I also became confused about assigning a data size because i was having to write part of the struct instead of the entire struct in one go.

But my problem now is with system strings and c_str() doesn't work with them. Why would wfstream help. It still only takes char * arguments doesn't it??

Share this post


Link to post
Share on other sites
This is a common method of obtaining a native string from a managed string:


array<unsigned char>^ nameBytes = System::Text::ASCIIEncoding::ASCII->GetBytes( name );
pin_ptr<unsigned char> pinnedName = &nameBytes[ 0 ];
LPCSTR myUnmanagedString = reinterpret_cast<LPCSTR>( pinnedName );



See my journal entry for more information about C++/CLI.

Share this post


Link to post
Share on other sites
Quote:

The problem with std::strings was when i was using the fstream read and write. I couldn't write out the struct of strings. I tried:

write((char *)temp.firstname.c_str(), sizeof(temp.name))

but when i read the string from the file all i got was jargen. I also became confused about assigning a data size because i was having to write part of the struct instead of the entire struct in one go.


The reason might be that sizeof(std::string) (which is the same for any string but varies widely between different implementations of string) does not report the lenght of the string. The string allocates the char buffer dynamically, so the size of the buffer is not in any way related to the size of the string object. For the length of the string use the size() method.

Share this post


Link to post
Share on other sites
Let's fix the console program first:


// The structure doesn't yet accomplish anything useful for us, and using a
// global variable for "scratch space" is incredibly ugly. What's wrong with
// local variables?

// There is no such thing as "ios::end" any more. And there is no such thing
// as "iostream.h" any more, either; you want <iostream>, with no .h.
void addInfo() { // where did your parentheses go?
std::ofstream file("info.txt", ios::app); // APPend to the file.
// You are writing to the file, so you want the stream open for output,
// not input. And don't use a flag to say that; just use the appropriate
// subclass. Finally, there's no need to call .open() explicitly - nor
// .close(), for that matter. RAII is your friend.
// To read lines of input into std::string objects, use the free function
// std::getline:
std::string firstname, lastname;
std::getline(std::cin, firstname);
std::getline(std::cin, lastname);
// Since our strings are *lines*, let's just write them as lines; we just put
// newlines between them, and can retrieve them later with std::getline in
// exactly the same way as we read them from the console.
file << firstname << "\n" << lastname << "\n";
// Text I/O is generally easier to work with. :) See, no need for size
// counts here, nor to worry about writing garbage that followed the null
// terminator of some ugly C-string.
}

void viewInfo() { // where did your parentheses go?
// Now we are going to read from a file, so it should be open for input.
// Starting at the beginning of the file is default, so the less said about
// that, the better.
ifstream file("info.txt");
// Don't use .eof() to control a loop, in normal cases. *It doesn't do what
// you think it does.* It will only report true when a read *has already
// failed* because of trying to read past the end of the file.
// Instead, *use the read condition itself* to control the loop:
std::string firstname, lastname;
while (std::getline(file, firstname) && std::getline(file, lastname)) {
std::cout << firstname << "\n" << lastname << "\n--------\n";
// Don't use std::endl as a replacement for newlines, please.
}
}

Share this post


Link to post
Share on other sites
I apreciate your help with showing me the more up to date c++ methods but it doesn't really help. I've already written a programme similar to that, but it got complex when i decided that i should be using structs so that later on i can do more fancy things like hashing.

Still my main problem stands, putting it into a windows form and to do this i need to know the best methods for dealing with system strings, not standard strings, unless there's a way i can get the form text boxes to deal with things other than system strings.

Sorry if i sound ungrateful its just ive been trying to do this for a while and its starting to frustrate me quite a bit. All the books ive been using show examples like the one you made but they all end up using char arrays when it comes to working with structs. Thats why i ended up giving up on working with strnigs and opted to just use character arrays instead.

Thanks for trying though.

Share this post


Link to post
Share on other sites
Quote:
Original post by originaldaemon
I apreciate your help with showing me the more up to date c++ methods but it doesn't really help. I've already written a programme similar to that, but it got complex when i decided that i should be using structs so that later on i can do more fancy things like hashing.

Still my main problem stands, putting it into a windows form and to do this i need to know the best methods for dealing with system strings, not standard strings, unless there's a way i can get the form text boxes to deal with things other than system strings.

Sorry if i sound ungrateful its just ive been trying to do this for a while and its starting to frustrate me quite a bit. All the books ive been using show examples like the one you made but they all end up using char arrays when it comes to working with structs. Thats why i ended up giving up on working with strnigs and opted to just use character arrays instead.

Thanks for trying though.


As a general rule, in programming, if you can't make two new tools work nicely with each other, and that's the only problem you've had with either of them, it is probably not a good idea to try to solve the problem by replacing one of the new tools with an older one.

One option is to eliminate one of the new tools altogether, especially if they do the same job. Why are you receiving a system::string, anyway? What kind of thing is your textBox?

Share this post


Link to post
Share on other sites
Quote:
Original post by Mike.Popoloski
I'm fairly certain he's using C++/CLI, in which case my previous post shows the preferred method of getting a native char array from a System::String.


Is there no direct way to get a std::string from it? A shame. Oh well. All that's needed to get a std::string from a native char array is to call the constructor, so that would do it, at least. :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this