Working with strings...

Started by
4 comments, last by gimp 23 years, 9 months ago
I have a few relatively basic things I''m trying to do with strings that I''m not quite getting yet... 1) Placing a string on the free store then using the pointer to dereference it.
    
string *newCommand = new string;
*newCommand.append(Mid(CommandLine,KeyStart,KeyStart + KeyEnd));
    
Or at least thats how I''d expect it to work. Then I cant seem to work out any smart ways of moving a string in to a vector. Short of looping through ever character is there a way of moving the data from a string in to a vector? I believe their both essentially dealing with arrays underneath. Thanks gimp
Chris Brodie
Advertisement
I think this will do what you want.
    string str = "Foobar\n";vector<char> vectChar(str.length()+1);strcpy(vectChar.begin(), str.c_str());    


...Syzygy
Ignore the previous poster..bad idea for many reasons. strcpy expects a C-style string, which std::string isn't (at least not necessarily). And since you want to copy to a vector anyway, it's just a bad idea to not use STL.

Here's two ways to do it using STL functions:
// assume you have a global string newCommand
vector vec (newCommand.size ()); // initialize to same size as string
copy (newCommand.begin (), newCommand.end (), vec.begin ());

// second way to do it: do it all in the constructor!!
vector vec (newCommand.begin (), newCommand.end ());

At this point, vec would be a vector of chars with each char from your string. Beware: std::strings are NOT "C" strings, so there is no terminating null at the end of the vector. If you look at the vector in the debugger (look at vec._First), you'll see garbage after the end of the string. That's because it's not null-terminated (nor does it need to be).

Also beware that the construction trick (2nd method) will only work if your vector is of type char. If you have another type (like int, or double), it won't work, but the first method will always work as long as there's a way to convert from char into your type of vector.

Now, I'm not sure why you're using Mid in your example; it won't work. CString::Mid requires that you use a CString from the MFC library, which you aren't, and the global namespace Mid command is in Visual Basic, not Visual C++.

In order to tell you what you should use, I'd have to know the type of CommandLine. Also, initializing the string can all be done in one line:
string *newCommand = new string (CommandLine.Mid (KeyStart, KeyEnd));
(that's what it would look like if CommandLine is a CString).

Please let me know what type CommandLine is and I can help you.

Edited by - Stoffel on July 13, 2000 2:28:57 PM
Thanks for the info on the vector to string. I thought there would be an ''STL way'' of doing it. I''m still to get used to that kind of stuff.

''Mid''...ahhh, that should be in there. Your right about it being a VB function, in fact I''ve been coding VB for about 6 years and well some old habits die hard. I wrote that along with Trim, LTrim, RTrim and CullWhiteSpace (Which collapses whitespace down to single spaces.). Admittedly I only quickly looked around for an alternative. I''d never touch MFC as my eventual goal is for platform independence.

Relating to the strings:
Ok, in my quest to become a better coder I often take a piece of code I''m proud of and post it to a newsgroup that looks like it has a large number of professional coders answering questions. My goal(request) is to have the code ruthlessly crushed and criticised,. and often I get what I want. From this I learn better ways of doing things. First on the list from everyone''s mouths was "Stop coding C in C++", next was "Stop trying to recreate the STL", and then "Don''t pass by value." etc.... For me these proved pivotal in changing my coding practices.

Ok, back to the question. What am I doing? Well basically I''m trying to code in a way that allows me to only ever have to allocate ram once for any particular piece of data. So the idea of this ''newing'' the string is just to malloc out the ram get a pointer to it and place the data on the process queue. (Can I do this with a reference? I''m still to learn of a concrete place for when to use ref vs pointers). The code fragment you see is an attempt to parse the arg''s, create a formatted string for processing and place it on a queue thats managed by a pluggable factory(which in turn calls the relevant function to handle that command.). This method processes all my console, config file and argument keypairs.

In any case thanks for your help stoffel.

gimp
Chris Brodie
I feel compelled to defend myself (at least for 1/2 of what I suggested).

Stoffel is correct that std::string is not a C-style string. However, std::string::c_str() IS. According to http://www.sgi.com/Technology/STL/basic_string.html c_str() "Returns a pointer to a null-terminated array of characters representing the string''s contents." This makes it easy to use string objects as input to non-stl functions, such as OutputDebugString and strcpy.

However, I will concede that it''s a little shady to copy into the iterator returned from vector::begin(). Although in 99.9% of the cases the vector class will be implemented as an array with begin() returning a pointer to the 0th element, I couldn''t find any stl rule *requiring* it, so it''s not *guaranteed* to be safe. (On the other hand, a quick look at the vector template in your stl headers will indicate whether or not this method is safe for your code.)

In the typical "game programmer" style, I was attempting to perform the task as quickly as possible (avoiding having to copy each character individually) and it caused me to compromise correctness somewhat. Apologies.

FWIW : I did test this before posting, and it does work (at least on the stl that comes with MSVC).
Yup, you''re right: string::c_str () will return a null-terminated string. But it was mostly the other reason that I had a problem using strcpy (that vector.begin () isn''t required to be a char*).

For instance, if you write your own allocator class, the vector might not be contiguous in memory. In this case, strcpy would really screw things up.

Another reason is that if you''re going to be using &ltstring> and &ltvector>, it seems superfluous to need to include the library &ltcstring> for this one command.

I understand about coming from the "game/hack" POV, no problem. I''m probably being too anal because I''m a game hobbiest and a professional programmer, not the other way around.

This topic is closed to new replies.

Advertisement