Changing All Words In A Vector To Uppercase

Hi everybody,

So got another challenge on my hands. I need to read all the inputs from cin and store those values in to a vector. Then I need to change all the vector values to uppercase and print results eight words at a time.

I have got the following for inputting the string elements in to a vector:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
#include <vector>

using std::string; using std::vector; using std::cout; using std::cin; using std::endl;

int main ()
{
    vector<string> v1;  // Create an empty vector
    string words;     // Create a string "words"
    
    while (cin >> words) {
        v1.push_back(words);
        }
    
    return 0;
}


This works just fine. But then to change toupper I tried the following but it doesn't work (as I'm sure you'll tell is obvious):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>
#include <vector>

using std::string; using std::vector; using std::cout; using std::cin; using std::endl;

int main ()
{
    vector<string> v1;  // Create an empty vector
    string words;     // Create a string "words"
    
    while (cin >> words) {
        v1.push_back(words);
        }
    for (auto &e : v1)  // for all elements "e" in vector v1
        e = toupper(e);
    
    return 0;
}


The error is "No matching function to call for 'toupper'. However I now have no idea how to solve this issue.

Help is appreciated!!

Thanks!
closed account (o3hC5Di1)
Hi there,

just a little hint here: toupper workson chars, not std::strings.
Luckily, std::string's are made up of char's, so if you iterate them and change every character to upper, that should work.

You may also want to check out the std::for_each algorithm, which allows to make a change to every item of a container (remember that a std::string is basically a container of chars).

Hope that helps you, please do get back to us if you need any further help.

All the best,
NwN
Try the following


1
2
3
4
for ( auto &s : v1 )
{
        for ( auto &c : s ) c = toupper( c );
}
Ok, so the error I was getting was then because I was trying to use a character conversion function on an entire string rather than iterating through which was then done by doing the range for function. It works great!

First though, vlad, could you maybe elaborate on how that function works? As I understand it it is using &s to reference characters in the vector v1 and then using &c to iterate through the characters in the string s, and then changing each character toupper. Is that roughly right?

I now however have a big problem, because the next part of the question I have never seen done before:

It wants me to print 8 words per line. I have NO clue how to solve that cookie! Really clueless! I'd like to keep it using simple coding because that's where I am in the book so far.

Here's the code as it stands now:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
#include <vector>

using std::string; using std::vector; using std::cout; using std::cin; using std::endl;

int main ()
{
    vector<string> v1;  // Create an empty vector
    string words;     // Create a string "words"
    
    while (cin >> words) {
        v1.push_back(words);
        }
    for (auto &s : v1) {
        for (auto &c : s) c = toupper(c);
        cout << s << " ";
        cout << endl;
    }
    
    return 0;
}
First though, vlad, could you maybe elaborate on how that function works? As I understand it it is using &s to reference strings in the vector v1 and then using &c to iterate through the characters in the string s, and then changing each character toupper. Is that roughly right?

Right

Do you know how to use stringstreams? They're pretty useful to read strings one word at a time
Last edited on
Hi maeriden,

No, haven't got that far yet I guess :p This is week 3 of C++ coding self-taught through a book, so still learning the 1+1's unfortunately.
Actually there is no need for them, I overlooked that every element in the vector is a single word
It all boils down to: print a word and a space 8 times, print a newline, 8 words, newline, etc
Use an int to keep track of how many words you have printed on every line. When that number is a multiple of 8 print the newline (this check is done using the modulo operator. If you're not familiar with it you can also check when it equals 8 and then set it back to 0)

I won't post the code, as it is an exercise, but if you post yours I can review it
1
2
3
4
5
6
7
8
9
10
11
const std::vector<std::string>::size_type N = 8;
std::vector<std::string>::size_type i = 0;

for ( const auto &s : v1 )
{
      std::cout << s;
      if ( ++i % N == N - 1 ) std::cout << std::endl;
      else std::cout << ' ';
}

if ( i % N != N = 1 ) std:;cout << std::endl;
Last edited on
Ok, sorry vlad, trying to gun this one by myself so this won't reflect your code. It looks like I am getting closer, but this code is just repeating the sentence twice, once on one line and then the rest one word per line.

In what ways can I tweak this existng code a little to get the result I need?

Thanks for all the help! It is through engaging with folks like yourselves that I really am starting to feel like I am getting a basic understanding! Thanks a lot!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
#include <vector>

using std::string; using std::vector; using std::cout; using std::cin; using std::endl;

int main ()
{
    vector<string> v1;  // Create an empty vector
    string words;     // Create a string "words"
    
    while (cin >> words) {
        v1.push_back(words);
    }
    for (auto &s : v1) {
        for (auto &c : s) c = toupper(c);
        cout << s << " ";
    }
    for (decltype(v1.size()) i = 0; i != 8; ++i)
        cout << v1[i] << '\n';
    cout << endl;
    
    return 0;
}
I showed you an example how to do this task. Please investigate the example. It is not interesting to uodate your own errors. Try to do it yourself.
Last edited on
A more than fair point vlad, my apologies!

I was having a look at your example and I'm not quite sure I follow... why is there the modulo there during the iteration? A problem I also seem to be having is where exactly to fit the code in, but that I can figure out through a little trial and error.

The other issue I'm getting is the first 2 lines... can a vector be initialised with an "="? It is giving me an error. Would defining it as just normal variables work the same way?

On the last line it gives me an error to say that "expression is not assignable"
Last edited on
Ok, latest update, I have stared and tried and tried at this thing for over 6 hours now and I still can't get it to work. I can get words shoved together, I can somehow get it to print every second word in a sentence (not sure how), I can get it to print a bunch of upside-down question marks, but nothing that I need.

I tried the example code above from vlad, but it just gives me a whole bunch of compile errors. I tried variations which compiled, but didn't give what I wanted unfortunately.

Please, if anybody has some more insights! I'm really ripping my hair out!!

I get how to print 8 elements of the string. That part is fine. My problem is how do I get it to print the next 8 on a new line and so-on and so-on. The challenge for me is the new line thing.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <string>
#include <vector>

using std::string; using std::vector; using std::cout; using std::cin; using std::endl;

int main ()
{
    vector<string> v1;  // Create an empty vector
    string words;     // Create a string "words"
    
    while (cin >> words) {
        v1.push_back(words);
    }
    for (auto &s : v1) {
        for (auto &c : s) c = toupper(c);
        cout << s << " ";
    }
    cout << '\n' ;

    const unsigned perLine = 8 ;
    decltype(v1.size()) wordCount ;

    for ( wordCount = 0; wordCount != v1.size() ; ++wordCount )
    {
        std::cout << v1[wordCount] << ' ' ;
        if ( (wordCount + 1) % perLine == 0 )  // evenly divisible?
            std::cout << '\n' ;
    }

    if ( wordCount % perLine != 0 )
        std::cout << '\n' ;

    
    return 0;
}
fire, you are an absolute legend!! It has got it working perfectly!! Just had to remove the "cout << s << " ";" and then it worked just perfectly.

It is going to take me a little time to fully look through and understand what you did. Adding a few breakpoints here and there has helped my dissect the code. By and large I get it though...

Just the decltype statement, is that taking the size of v1 and putting it in to a value "wordCount"?

The other thing I find interesting is the (word count + 1) , why can't one use ++wordCount? (I tried it and it jumps every second letter.)

As I understand it the modulo % divides a value and returns true if it has no decimal points... so how exactly does 8 % 8 == 0 work? Is it because that is the only number that 8 can divide evenly? doesn't 0 reflect false bool and 1 equal true, or have I got them mixed up?

Last thing, the very last if statement, is that really necessary? It seems to me to be a redundant piece of code?

A really huge THANK YOU!! My brain was really beginning to spin!
Just the decltype statement, is that taking the size of v1 and putting it in to a value "wordCount"?

Since I extracted it from your code, I assumed you knew what it was doing. decltype returns the type of an expression. In this particular case the type of the value returned by v1.size(), so that wordCount is given that type.


The other thing I find interesting is the (word count + 1) , why can't one use ++wordCount? (I tried it and it jumps every second letter.)

Because the point of the code is not to increment wordCount, but to use wordCount+1. wordCount is already incremented every iteration of the for loop. wordCount+1 must be used because the index values for arrays/vectors are 0 to size-1, and it's required for the modulus to work the way it should.


As I understand it the modulo % divides a value and returns true if it has no decimal points... so how exactly does 8 % 8 == 0 work?

You understand it incorrectly. Modulo returns the remainder of a division operation. So, 8 % 8 is 0 and 7 % 8 is 7.


Last thing, the very last if statement, is that really necessary? It seems to me to be a redundant piece of code?

It's only necessary if you want to consistently end on a new line.

Last edited on
Ahhh!! Ok! It all makes sense now!

You can clearly see why I was struggling to answer the question!!

Thank you! This really helps me a bucket load!!
Topic archived. No new replies allowed.