-1

I'm new to C++. I'm trying to solve a problem which goes something like this:

Q: create varies string vectors, and using iterator to change those strings to uppercase.

Below is the code I came up with. However, the IDE always output error. Because I'm new to C++, I don't have enough knowledge to fix the problem.

#include <iostream>
#include <string>
#include <vector>
#include <iterator>
using namespace std;

void checkAndPrint(vector<string> &vec) {
    cout << "content: [";
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        for (char c : it) {
            c = toupper(c);
            cout << c;
        }
    }
    cout << "]\n" << endl;
}

int main() {

    vector<string> s1;
    vector<string> s2(10);
    vector<string> s3(10, "hello");
    vector<string> s4{10, "world"};
    vector<string> s5{"good", "morning"};
    vector<string> s6{10, "10"};

    checkAndPrint(s1);
    checkAndPrint(s2);
    checkAndPrint(s3);
    checkAndPrint(s4);
    checkAndPrint(s5);
    checkAndPrint(s6);
}

Error:

error: invalid range expression of type 'std::__1::__wrap_iter<std::__1::basic_string<char> *>'; did you mean to dereference it with '*'?
        for (char c : it) {
                      ^
                      *
halfer
  • 19,824
  • 17
  • 99
  • 186
Thor
  • 9,638
  • 15
  • 62
  • 137
  • It would be great if you gave us the actual error and indicated which line its from... (P.S: I'm curious as to why you used a foreach loop on the string, but a "regular" for loop on the vector) – Borgleader Feb 16 '16 at 00:45
  • 2
    P.P.S: *did you mean to dereference it with '*'?* listen to your compiler. – Borgleader Feb 16 '16 at 00:47
  • That is an impressively clear error message, compared to what [gcc produces](http://coliru.stacked-crooked.com/a/bebfe741c5f7312d). – Baum mit Augen Feb 16 '16 at 00:57

2 Answers2

2

You need to dereference the iterator:

for (char c : *it)

or use a second range for loop:

for (auto &v : vec) {
    for (char c : v) { ...

Also note that currently you are not modifying the original vectors as

for (char c : *it)

operates on copies of the original chars. To fix that, iterate over references instead, i.e.

for (char &c : *it)

Lastly, note that you should add a cast as in Do I need to cast to unsigned char before calling toupper? You also forgot to #include <cctype> which provides toupper.

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
1

it is the iterator, not the string itself. It's essentially a pointer to a string that changes which string it points to for each iteration, so you have to dereference it before you can access each character in the for loop:

for (char c : it) {

should become:

for (char c : *it) {

Additionally, if you want the strings themselves to be updated so that they're uppercased, you need to use a char reference in the second for loop, like so:

for (char& c : *it) {

The way you have it right now, you're changing a new variable c (a copy, essentially) that won't be reflected in the original string. Using a char reference will let you mutate the characters in the original string.

huu
  • 7,032
  • 2
  • 34
  • 49
  • Thank you so much for your help!! pointers and reference are so confusing lol – Thor Feb 16 '16 at 00:50
  • 1
    @dzjustinli, it's only through pain that we mortals can hope to become familiar enough with them to not make mistakes -- it gets better with time. I will second Baum mit Augen's suggestion here to use a non-iterator loop for your first `for` loop. It lets you get away with not having to deal with pointers at all, and only references. – huu Feb 16 '16 at 00:53