Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. ATL / WTL / STL
  4. std::string

std::string

Scheduled Pinned Locked Moved ATL / WTL / STL
helpc++question
18 Posts 8 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    LCI
    wrote on last edited by
    #1

    I have a .dll that i am writing and cannot use standard MFC classes such as CString to parse a blob of data. So i am using std::string but i have never used this before and am so confused. I need to search a string for a key word. Once i find the keyword, i have to parse the data afterwards to pick out the necessary data that i need. I am using the find method but just stuck and confused to accomplish my goal. Can anyone offer some examples or help? E.g. If i have a string that looks like xxxcdfdftbvbfggbnghghg Name: Todd Shields ccfgfgnfgnrri DOB:091580 hgertrtreggeegegggggggggggg But i want to get the name and the DOB. There is no standard in terms of how much space is allocated for name or DOB. I just have to find it and get the name and DOB from the string. Any input is appreciated.

    C I 2 Replies Last reply
    0
    • L LCI

      I have a .dll that i am writing and cannot use standard MFC classes such as CString to parse a blob of data. So i am using std::string but i have never used this before and am so confused. I need to search a string for a key word. Once i find the keyword, i have to parse the data afterwards to pick out the necessary data that i need. I am using the find method but just stuck and confused to accomplish my goal. Can anyone offer some examples or help? E.g. If i have a string that looks like xxxcdfdftbvbfggbnghghg Name: Todd Shields ccfgfgnfgnrri DOB:091580 hgertrtreggeegegggggggggggg But i want to get the name and the DOB. There is no standard in terms of how much space is allocated for name or DOB. I just have to find it and get the name and DOB from the string. Any input is appreciated.

      C Offline
      C Offline
      Christian Graus
      wrote on last edited by
      #2

      LCI wrote: So i am using std::string but i have never used this before and am so confused This is one good reason to prefer the standard library, you'll know it when you need it :-) What you really need is regex, I wonder if you're able to use the regex implimentation that boost offers ? Otherwise : string s = "xxxcdfdftbvbfggbnghghg Name: Todd Shields ccfgfgnfgnrri DOB:091580 hgertrtreggeegegggggggggggg"; size_t n = s.find_first_of("Name : ") + 7; // ( 7 is the length of the string we searched for size_t nLast = s.find_first_of(" ", n); nLast = s.find_first_of(" ", nLast + 1); // Need to search twice because of the space in the name string name = s.substr(n, nLast - n); This is REALLY fragile. Ideally, you'd know the string that comes after ( ccfgfgnfgnrri in this case ), so you can search for the item AFTER the name, instead of having to count on there being a certain number of whitespace chars IN the name. The date is obviously easier, but either way, CString wouldn't help much, regex is the real way to deal with this. Christian Graus - Microsoft MVP - C++

      X L 2 Replies Last reply
      0
      • C Christian Graus

        LCI wrote: So i am using std::string but i have never used this before and am so confused This is one good reason to prefer the standard library, you'll know it when you need it :-) What you really need is regex, I wonder if you're able to use the regex implimentation that boost offers ? Otherwise : string s = "xxxcdfdftbvbfggbnghghg Name: Todd Shields ccfgfgnfgnrri DOB:091580 hgertrtreggeegegggggggggggg"; size_t n = s.find_first_of("Name : ") + 7; // ( 7 is the length of the string we searched for size_t nLast = s.find_first_of(" ", n); nLast = s.find_first_of(" ", nLast + 1); // Need to search twice because of the space in the name string name = s.substr(n, nLast - n); This is REALLY fragile. Ideally, you'd know the string that comes after ( ccfgfgnfgnrri in this case ), so you can search for the item AFTER the name, instead of having to count on there being a certain number of whitespace chars IN the name. The date is obviously easier, but either way, CString wouldn't help much, regex is the real way to deal with this. Christian Graus - Microsoft MVP - C++

        X Offline
        X Offline
        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        wrote on last edited by
        #3

        Christian Graus wrote: This is REALLY fragile. Ideally, you'd know the string that comes after ( ccfgfgnfgnrri in this case ), so you can search for the item AFTER the name, instead of having to count on there being a certain number of whitespace chars IN the name. The date is obviously easier, but either way, CString wouldn't help much, regex is the real way to deal with this. It looks like the string actually contains key-value pairs. In that case he'd know the next token. BTW, find_first_of, substring, ... are regular expressions translated to human-readable form.

        C 1 Reply Last reply
        0
        • X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

          Christian Graus wrote: This is REALLY fragile. Ideally, you'd know the string that comes after ( ccfgfgnfgnrri in this case ), so you can search for the item AFTER the name, instead of having to count on there being a certain number of whitespace chars IN the name. The date is obviously easier, but either way, CString wouldn't help much, regex is the real way to deal with this. It looks like the string actually contains key-value pairs. In that case he'd know the next token. BTW, find_first_of, substring, ... are regular expressions translated to human-readable form.

          C Offline
          C Offline
          Christian Graus
          wrote on last edited by
          #4

          Sloppy Joseph wrote: BTW, find_first_of, substring, ... are regular expressions translated to human-readable form. That's a pretty weird point of view. Christian Graus - Microsoft MVP - C++

          K 1 Reply Last reply
          0
          • C Christian Graus

            Sloppy Joseph wrote: BTW, find_first_of, substring, ... are regular expressions translated to human-readable form. That's a pretty weird point of view. Christian Graus - Microsoft MVP - C++

            K Offline
            K Offline
            Kevin McFarlane
            wrote on last edited by
            #5

            Regular expressions are unreadable. That's why every one should be commented. I imagine that if I were writing a regular expression for this I might well come up with comments such as "find first of." I once had to maintain a Perl script which was a mass of uncommented regular expressions and I've taken a dim view of them ever since. They're very powerful and I should use them more but they're a pain in the neck. Recently I was trying to do a RegEx search in the VS IDE. My discoveries for this particular RegEX were that: 1. It worked using a tool such as Expresso. 2. I had to change the syntax to get it to work in VS. 3. I couldn't get either the origibal or the changed syntax to work in TextPad. That's another reason why I hate regular expressions. :(( Maybe I just don't have the mental make-up to be comfortable with RegEx. Maybe it's why I also hate Perl. It's the only language out of Perl, C, C++, VB (all variants), C#, Java, Fortran, Eiffel, Pascal, Python, JavaScript, that I hate. Kevin

            C 1 Reply Last reply
            0
            • K Kevin McFarlane

              Regular expressions are unreadable. That's why every one should be commented. I imagine that if I were writing a regular expression for this I might well come up with comments such as "find first of." I once had to maintain a Perl script which was a mass of uncommented regular expressions and I've taken a dim view of them ever since. They're very powerful and I should use them more but they're a pain in the neck. Recently I was trying to do a RegEx search in the VS IDE. My discoveries for this particular RegEX were that: 1. It worked using a tool such as Expresso. 2. I had to change the syntax to get it to work in VS. 3. I couldn't get either the origibal or the changed syntax to work in TextPad. That's another reason why I hate regular expressions. :(( Maybe I just don't have the mental make-up to be comfortable with RegEx. Maybe it's why I also hate Perl. It's the only language out of Perl, C, C++, VB (all variants), C#, Java, Fortran, Eiffel, Pascal, Python, JavaScript, that I hate. Kevin

              C Offline
              C Offline
              Christian Graus
              wrote on last edited by
              #6

              Kevin McFarlane wrote: Regular expressions are unreadable. As is C++, C# and Japanese, for people who don't know them. I agree that they can take a moment to work through, but they are hardly unreadable. Kevin McFarlane wrote: 1. It worked using a tool such as Expresso. 2. I had to change the syntax to get it to work in VS. 3. I couldn't get either the origibal or the changed syntax to work in TextPad. TextPad ? I agree that it's a pain that you need to mangle regex to get it to work in the IDE. But Expresso regex will work in C#/VB.NET code, no hassles. I do it all the time. Christian Graus - Microsoft MVP - C++

              K 1 Reply Last reply
              0
              • C Christian Graus

                Kevin McFarlane wrote: Regular expressions are unreadable. As is C++, C# and Japanese, for people who don't know them. I agree that they can take a moment to work through, but they are hardly unreadable. Kevin McFarlane wrote: 1. It worked using a tool such as Expresso. 2. I had to change the syntax to get it to work in VS. 3. I couldn't get either the origibal or the changed syntax to work in TextPad. TextPad ? I agree that it's a pain that you need to mangle regex to get it to work in the IDE. But Expresso regex will work in C#/VB.NET code, no hassles. I do it all the time. Christian Graus - Microsoft MVP - C++

                K Offline
                K Offline
                Kevin McFarlane
                wrote on last edited by
                #7

                C++ and C# resemble something like ordinary English. (Though I'd prefer those languages to be even more readable than they are.) Regular Expressions don't. Mentally you just have to do a lot more work to understand them. Re: Expresso, I was referring to RegEx search in the Search/Replace dialog. There I found there were differences. Perhaps it's just a mindset thing. It's probably why I detest Perl. Though it's not just the RegEx why I hate Perl. But I think Perl is one of those languages you either love or hate depending on your mental makeup. My current boss loves Perl. He didn't seem to mind when I said I hated it.:) Kevin

                C 1 Reply Last reply
                0
                • K Kevin McFarlane

                  C++ and C# resemble something like ordinary English. (Though I'd prefer those languages to be even more readable than they are.) Regular Expressions don't. Mentally you just have to do a lot more work to understand them. Re: Expresso, I was referring to RegEx search in the Search/Replace dialog. There I found there were differences. Perhaps it's just a mindset thing. It's probably why I detest Perl. Though it's not just the RegEx why I hate Perl. But I think Perl is one of those languages you either love or hate depending on your mental makeup. My current boss loves Perl. He didn't seem to mind when I said I hated it.:) Kevin

                  C Offline
                  C Offline
                  Christian Graus
                  wrote on last edited by
                  #8

                  Kevin McFarlane wrote: Re: Expresso, I was referring to RegEx search in the Search/Replace dialog. There I found there were differences. Yeah I know. Like I said, I hate that, too. Christian Graus - Microsoft MVP - C++

                  1 Reply Last reply
                  0
                  • C Christian Graus

                    LCI wrote: So i am using std::string but i have never used this before and am so confused This is one good reason to prefer the standard library, you'll know it when you need it :-) What you really need is regex, I wonder if you're able to use the regex implimentation that boost offers ? Otherwise : string s = "xxxcdfdftbvbfggbnghghg Name: Todd Shields ccfgfgnfgnrri DOB:091580 hgertrtreggeegegggggggggggg"; size_t n = s.find_first_of("Name : ") + 7; // ( 7 is the length of the string we searched for size_t nLast = s.find_first_of(" ", n); nLast = s.find_first_of(" ", nLast + 1); // Need to search twice because of the space in the name string name = s.substr(n, nLast - n); This is REALLY fragile. Ideally, you'd know the string that comes after ( ccfgfgnfgnrri in this case ), so you can search for the item AFTER the name, instead of having to count on there being a certain number of whitespace chars IN the name. The date is obviously easier, but either way, CString wouldn't help much, regex is the real way to deal with this. Christian Graus - Microsoft MVP - C++

                    L Offline
                    L Offline
                    LCI
                    wrote on last edited by
                    #9

                    Great.. thanks for all your input. I also wrote a small method that will strip all the spaces from the end of an basic_string up until is reaches text. So a string like "This is a test " .. would be "This is a test" once the method is complete. Something is not working correctly though. typedef std::string::size_type size_type; std::string AnyString; char MySpace = ' '; size_type CHAR_INDEX; CHAR_INDEX = AnyString.size();//AnyString.rfind(MySpace); for (size_type i = CHAR_INDEX;AnyString[i]== MySpace; i--) AnyString.erase(i,1); The above source only works when stripping one space, like from "2003 " to "2003". If i have "2003 ", it does not work. Can anyone tell me what i am doing wrong here?

                    R L K 3 Replies Last reply
                    0
                    • L LCI

                      I have a .dll that i am writing and cannot use standard MFC classes such as CString to parse a blob of data. So i am using std::string but i have never used this before and am so confused. I need to search a string for a key word. Once i find the keyword, i have to parse the data afterwards to pick out the necessary data that i need. I am using the find method but just stuck and confused to accomplish my goal. Can anyone offer some examples or help? E.g. If i have a string that looks like xxxcdfdftbvbfggbnghghg Name: Todd Shields ccfgfgnfgnrri DOB:091580 hgertrtreggeegegggggggggggg But i want to get the name and the DOB. There is no standard in terms of how much space is allocated for name or DOB. I just have to find it and get the name and DOB from the string. Any input is appreciated.

                      I Offline
                      I Offline
                      Igor Vigdorchik
                      wrote on last edited by
                      #10

                      Active Template Library (ATL) has a regex class[^]

                      1 Reply Last reply
                      0
                      • L LCI

                        Great.. thanks for all your input. I also wrote a small method that will strip all the spaces from the end of an basic_string up until is reaches text. So a string like "This is a test " .. would be "This is a test" once the method is complete. Something is not working correctly though. typedef std::string::size_type size_type; std::string AnyString; char MySpace = ' '; size_type CHAR_INDEX; CHAR_INDEX = AnyString.size();//AnyString.rfind(MySpace); for (size_type i = CHAR_INDEX;AnyString[i]== MySpace; i--) AnyString.erase(i,1); The above source only works when stripping one space, like from "2003 " to "2003". If i have "2003 ", it does not work. Can anyone tell me what i am doing wrong here?

                        R Offline
                        R Offline
                        Roland Pibinger
                        wrote on last edited by
                        #11

                        LCI wrote: for (size_type i = CHAR_INDEX;AnyString[i]== MySpace; i--) AnyString.erase(i,1); The above source only works when stripping one space, like from "2003 " to "2003". If i have "2003 ", it does not work. Can anyone tell me what i am doing wrong here? You probably want a 'trim_back()' function. It must also work for 'unusual' cases like empty strings and strings that contain only white space. Also note that string::size_type is unsigned (cannot be less than 0).

                        #include <string>
                        #include <iostream>

                        std::string& trim_back (std::string& str)
                        {
                        using namespace std;
                        while (str.size()) {
                        if (isspace (str[str.size()-1])) {
                        str.erase(str.size()-1);
                        } else {
                        break;
                        }
                        }
                        return str;
                        }

                        int main()
                        {
                        using namespace std;

                        string test ("2003 "),
                        whitespaceOnly (" \n\t"),
                        empty;

                        cout << '|' << trim_back(test) << '|' << endl;
                        cout << '|' << trim_back(whitespaceOnly) << '|' << endl;
                        cout << '|' << trim_back(empty) << '|' << endl;

                        return 0;
                        }

                        1 Reply Last reply
                        0
                        • L LCI

                          Great.. thanks for all your input. I also wrote a small method that will strip all the spaces from the end of an basic_string up until is reaches text. So a string like "This is a test " .. would be "This is a test" once the method is complete. Something is not working correctly though. typedef std::string::size_type size_type; std::string AnyString; char MySpace = ' '; size_type CHAR_INDEX; CHAR_INDEX = AnyString.size();//AnyString.rfind(MySpace); for (size_type i = CHAR_INDEX;AnyString[i]== MySpace; i--) AnyString.erase(i,1); The above source only works when stripping one space, like from "2003 " to "2003". If i have "2003 ", it does not work. Can anyone tell me what i am doing wrong here?

                          L Offline
                          L Offline
                          Lost User
                          wrote on last edited by
                          #12

                          I recommend you look at boost. I recently installed it and it is a fantastic library. It includes string trimming functions - e.g.:

                          #include <boost/algorithm/string.hpp>
                          ...
                          std::string str = "Hello ";
                          boost::trim(str);

                          1 Reply Last reply
                          0
                          • L LCI

                            Great.. thanks for all your input. I also wrote a small method that will strip all the spaces from the end of an basic_string up until is reaches text. So a string like "This is a test " .. would be "This is a test" once the method is complete. Something is not working correctly though. typedef std::string::size_type size_type; std::string AnyString; char MySpace = ' '; size_type CHAR_INDEX; CHAR_INDEX = AnyString.size();//AnyString.rfind(MySpace); for (size_type i = CHAR_INDEX;AnyString[i]== MySpace; i--) AnyString.erase(i,1); The above source only works when stripping one space, like from "2003 " to "2003". If i have "2003 ", it does not work. Can anyone tell me what i am doing wrong here?

                            K Offline
                            K Offline
                            Kevin McFarlane
                            wrote on last edited by
                            #13

                            Try

                            inline string trim_right(const string& source, const string& t = " ")
                            {
                            string str = source;
                            return str.erase(source.find_last_not_of(t) + 1);
                            }

                            inline string trim_left(const string& source, const string& t = " ")
                            {
                            string str = source;
                            return str.erase(0, source.find_first_not_of(t));
                            }

                            inline string trim(const string& source, const string& t = " ")
                            {
                            return trim_left(trim_right(source, t), t);
                            }

                            Kevin

                            X 1 Reply Last reply
                            0
                            • K Kevin McFarlane

                              Try

                              inline string trim_right(const string& source, const string& t = " ")
                              {
                              string str = source;
                              return str.erase(source.find_last_not_of(t) + 1);
                              }

                              inline string trim_left(const string& source, const string& t = " ")
                              {
                              string str = source;
                              return str.erase(0, source.find_first_not_of(t));
                              }

                              inline string trim(const string& source, const string& t = " ")
                              {
                              return trim_left(trim_right(source, t), t);
                              }

                              Kevin

                              X Offline
                              X Offline
                              XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                              wrote on last edited by
                              #14

                              Kevin McFarlane wrote: Try Don't! inline string trim_right(const string& source, const string& t = " "){ string str = source; return str.erase(source.find_last_not_of(t) + 1);} 1. You search only for " ", not for white space (e.g. '\t') 2. find_last_not_of() returns npos when no match is found (which is not an appropriate input for erase) 3. You return by value thus duplicating the string unnecessarily. In sum, your 'solution' is incorrect and inefficient, but fine otherwise. :suss:

                              K 2 Replies Last reply
                              0
                              • X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

                                Kevin McFarlane wrote: Try Don't! inline string trim_right(const string& source, const string& t = " "){ string str = source; return str.erase(source.find_last_not_of(t) + 1);} 1. You search only for " ", not for white space (e.g. '\t') 2. find_last_not_of() returns npos when no match is found (which is not an appropriate input for erase) 3. You return by value thus duplicating the string unnecessarily. In sum, your 'solution' is incorrect and inefficient, but fine otherwise. :suss:

                                K Offline
                                K Offline
                                Kevin McFarlane
                                wrote on last edited by
                                #15

                                I copied the code from somewhere. It seemed to work for me so I didn't check its details. Still, I think a trim function should have been part of basic_string (if only to prevent incorrect implementations like this!:)). It's a common enough operation. Kevin

                                N 1 Reply Last reply
                                0
                                • K Kevin McFarlane

                                  I copied the code from somewhere. It seemed to work for me so I didn't check its details. Still, I think a trim function should have been part of basic_string (if only to prevent incorrect implementations like this!:)). It's a common enough operation. Kevin

                                  N Offline
                                  N Offline
                                  Nemanja Trifunovic
                                  wrote on last edited by
                                  #16

                                  Kevin McFarlane wrote: Still, I think a trim function should have been part of basic_string Nah. std::basic_string is already too big and fat[^]


                                  My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.

                                  1 Reply Last reply
                                  0
                                  • X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

                                    Kevin McFarlane wrote: Try Don't! inline string trim_right(const string& source, const string& t = " "){ string str = source; return str.erase(source.find_last_not_of(t) + 1);} 1. You search only for " ", not for white space (e.g. '\t') 2. find_last_not_of() returns npos when no match is found (which is not an appropriate input for erase) 3. You return by value thus duplicating the string unnecessarily. In sum, your 'solution' is incorrect and inefficient, but fine otherwise. :suss:

                                    K Offline
                                    K Offline
                                    Kevin McFarlane
                                    wrote on last edited by
                                    #17

                                    Sloppy Joseph wrote: You search only for " ", not for white space (e.g. '\t') Actually it does handle '\t', as I've only specified a default argument. Sloppy Joseph wrote: find_last_not_of() returns npos when no match is found (which is not an appropriate input for erase) Agreed, but still seems to work anyway. Sloppy Joseph wrote: You return by value thus duplicating the string unnecessarily. OK, how about this?

                                    inline string& trim(string& s, const string& t)
                                    {
                                    string::size_type st1, st2;
                                    st1 = s.find_first_not_of(t);

                                    if (st1 != string::npos)
                                    {
                                    	st2 = s.find\_last\_not\_of(t) + 1;
                                    	s = s.substr(st1, st2 - st1);
                                    }
                                    else
                                    {
                                    	s.clear();
                                    }
                                    
                                    return s;
                                    

                                    }

                                    Kevin

                                    X 1 Reply Last reply
                                    0
                                    • K Kevin McFarlane

                                      Sloppy Joseph wrote: You search only for " ", not for white space (e.g. '\t') Actually it does handle '\t', as I've only specified a default argument. Sloppy Joseph wrote: find_last_not_of() returns npos when no match is found (which is not an appropriate input for erase) Agreed, but still seems to work anyway. Sloppy Joseph wrote: You return by value thus duplicating the string unnecessarily. OK, how about this?

                                      inline string& trim(string& s, const string& t)
                                      {
                                      string::size_type st1, st2;
                                      st1 = s.find_first_not_of(t);

                                      if (st1 != string::npos)
                                      {
                                      	st2 = s.find\_last\_not\_of(t) + 1;
                                      	s = s.substr(st1, st2 - st1);
                                      }
                                      else
                                      {
                                      	s.clear();
                                      }
                                      
                                      return s;
                                      

                                      }

                                      Kevin

                                      X Offline
                                      X Offline
                                      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                                      wrote on last edited by
                                      #18

                                      Kevin McFarlane wrote: Actually it does handle '\t', as I've only specified a default argument. Well, you require the user to define the white spaces for you? This is, at least, not user friendly (answer quickly, which chars are white space? Is '\n' a white space, is '\a'?). Hint: isspace. Agreed, but still seems to work anyway. An questionable answer for a professional software developer. OK, how about this? if (st1 != string::npos) { st2 = s.find_last_not_of(t) + 1; s = s.substr(st1, st2 - st1); } substr() produces a (partial) copy which is assigned (= copied again) to s. You can do it all in place.

                                      1 Reply Last reply
                                      0
                                      Reply
                                      • Reply as topic
                                      Log in to reply
                                      • Oldest to Newest
                                      • Newest to Oldest
                                      • Most Votes


                                      • Login

                                      • Don't have an account? Register

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • World
                                      • Users
                                      • Groups