Thread: vector of strings with iterators.

  1. #1
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446

    vector of strings with iterators.

    Hello all,

    For learning purposes, I've built a vector of strings and tried to access each element on each string performing an uppercase conversion on all characters. I wanted also to use iterators. I produced the following code:
    Code:
    string strtemp;
    for (vector<string>::const_iterator i_iter(vstr.begin()); i_iter != vstr.end(); ++i_iter) {
        strtemp = *i_iter;
        for (string::iterator str_iter(strtemp.begin()); str_iter != strtemp.end(); ++str_iter) {
            *str_iter = toupper(*str_iter); //Warning reports this line
        }
    }
    The code works but...

    1. I get on VC++ 2005 Express a warning about possile loss of data from a conversion from int to char. I read of the help file concerning this warning code (C4244). I think it is a level 3 warning that warns about a __int64 conversion to unsigned int. Question is why?

    Under Dev-C++, this code produces no warning even with -Wall and -Wextra. So my best guess before I decided to bother you good people, is that this has something to do with Microsoft's support for sized intergers. Namely this __int64 type. Is this so? Are iterators being declared as __int64 under VC++ 2005?

    2. I couldn't find a way to access each string directly after the 2nd FOR loop. Hence having to create the temporary string. My best shoot for the second loop was:
    Code:
    for (string::iterator str_iter = *i_iter.begin(); str_iter != *i_iter.end(); ++str_iter)
    Which produced an compile-time error. How can I directly access the strings inside the vector using iterators?

  2. #2
    Registered User
    Join Date
    Aug 2005
    Posts
    1,267
    I would do it this way:
    Code:
    vector<string> list;
    // populate list not shown
    vector<string>::iterator it;
    for(it = list.begin; it != list.end(); it++)
    {
       string str = *it;
       transform(str.begin(),str.end(), str.begin(), tupper);
    }
    alternative
    Code:
    	vector<string>::iterator it;
    	for(it = list.begin(); it != list.end(); it++)
    	{
    		string str = *it;
    		transform((*it).begin(),(*it).end(),(*it).begin(),toupper);
    		cout << (*it) << endl;
    	}
    Last edited by Ancient Dragon; 05-30-2006 at 06:47 PM.

  3. #3
    geek SilentStrike's Avatar
    Join Date
    Aug 2001
    Location
    NJ
    Posts
    1,141
    If you want to see how to actually manipulate the data using iterators, check out this code, which uppercases input text line by line.

    The problem with your code is that you were making a temporary copy, and only modifying the copy.

    Code:
    #include <string>
    #include <vector>
    #include <iostream>
    #include <cctype>
    
    using namespace std;
    
    int main() {
      vector<string> lines;
      string line;
      while (getline(cin, line)) {
        lines.push_back(line);
      }
      for (vector<string>::iterator vec_it = lines.begin(); vec_it != lines.end();
           ++vec_it) {
        for (string::iterator str_it = vec_it->begin(); str_it != vec_it->end();
             ++str_it) {
          *str_it = toupper(*str_it);
        }
      }
      for (vector<string>::iterator vec_it = lines.begin(); vec_it != lines.end();
           ++vec_it) {
        cout << *vec_it << "\n";
      }
    }
    Prove you can code in C++ or C# at TopCoder, referrer rrenaud
    Read my livejournal

  4. #4
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Thanks Ancient and Silent.

    I wanted indeed to traverse the string instead of opting for a more elegant solution like the one offered by Ancient. The objective was to test my study of iterators.

    The dereference operator -> was exactly what I was missing. It worked like a charm. A quick read of Stroustrup also helped me realize that p->m is equivalent to (*p).m, the type of syntax I was trying to reach in the beginning and couldn't.

    I was still having an error. I declared the first iterator as const since it was not going to change any data. It was easily solved.

    However... One problem still persists. It's more a pet peeve, but I would like to understand why VC++ still warns me about an implicit conversion when dereferencing the string.

  5. #5
    Registered User
    Join Date
    May 2006
    Posts
    903
    Another solution:

    Code:
    void StrToUpper(std::string& str) {
        for(int i = 0; i < str.size(); i++)
            str[i] = toupper(str[i]);
    }
    
    int main() {
        std::vector<std::string> v_str;
        // fill it here
    
        for_each(v_str.begin(); v_str.end(); StrToUpper);
    }

  6. #6
    geek SilentStrike's Avatar
    Join Date
    Aug 2001
    Location
    NJ
    Posts
    1,141
    The warning is not because you are derefencing the character, but rather because toupper returns an int.

    http://www.sensi.org/~alec/man/man3/toupper.html
    Prove you can code in C++ or C# at TopCoder, referrer rrenaud
    Read my livejournal

  7. #7
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Ah! Didn't think to check that. Thank you again Silent.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strings Program
    By limergal in forum C++ Programming
    Replies: 4
    Last Post: 12-02-2006, 03:24 PM
  2. Problem with Strings, Please help!
    By varus in forum C++ Programming
    Replies: 8
    Last Post: 11-27-2006, 11:47 PM
  3. Programming using strings
    By jlu0418 in forum C++ Programming
    Replies: 5
    Last Post: 11-26-2006, 08:07 PM
  4. Reading strings input by the user...
    By Cmuppet in forum C Programming
    Replies: 13
    Last Post: 07-21-2004, 06:37 AM
  5. menus and strings
    By garycastillo in forum C Programming
    Replies: 3
    Last Post: 04-29-2002, 11:23 AM