Error trying to use a for loop with input validation using tolower() and .length()

*Disclaimer*
This is a homework assignment, I asked my teacher about the issue and he gave me great advice, which I took. But I am stuck with the formatting of this situation. I have looked online and have found many different examples of one part or another, but I still cant see what I'm doing wrong. I"m hoping its just a silly mistake and just not me trying to do something completely wrong.

Here is the portion of my code I am having trouble with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <cctype>
#include <string>
using namespace std;

int main()
{
  string selection;
  auto selection_temp = 0;
  int i;


cout << "Please enter one of the following to calculate the temperature on: cat, cot, cap." <<endl;
cin >> selection;
string s = "";

  for (i=0; i <= selection.length(); i++){
    s = s + (char)(tolower(selection[i]));
  }
}

The error I am getting with from Replit is:

"[cquery] invalid operands to binary expression ('std::__cxx11::string' (aka 'basic_string<char>') and 'int')"

I'm not sure what that even means. But on line 17 the ...'s + (tolower(selection[i]))' is all underlined as the error. I'm guessing that I just haven't structured this correctly? But all the examples I find seem to suggest that I don't have any issues. But then again I haven't found anything on someone trying to use this method exactly for input verification.

Not going to lie the 'selection[i]' portion of line 17 I don't fully understand, I only have it because it seems to be what I see people doing. If there is an easy explanation of why we put the 'i' in brackets, it would be much appreciated.

Thanks for you time!
Last edited on
it thinks tolower gave an integer (this is correct, but its horrible, probably a leftover from C). cast it to char:
s = s + (char)(tolower(selection[i]));
or better:
s += (char)(tolower(selection[i]));

also watch that length,
for (i=0; i < selection.length(); i++) //not <=
Last edited on
PLEASE learn to use code tags, they make reading and commenting on source code MUCH easier.

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

HINT: you can edit your post and add code tags.

Some formatting & indentation would not hurt either

Your code with code tags, some formatting and a couple of changes/additions:
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
#include <iostream>
#include <cctype>
#include <string>

using namespace std;

int main()
{
   string selection;
   auto selection_temp = 0;
   int i;

   cout << "Please enter one of the following to calculate the temperature on: 16 cat, cot, cap." << endl;
   cin >> selection;

   string s;

   for (i = 0; i <= selection.length(); i++)
   {
      s += static_cast<char>(::tolower(selection[i])); // C++ cast to char
      // s += (char) ::tolower(selection[i]); // C casts can create problems
   }

   // let's display the lower-cased string
   std::cout << s << '\n';
}


I apologize I should have mentioned I'm in a intro to C++ class right now.

that particular line I made with the teacher's suggestion.

But I think I get what you are saying, in that for some reason is an int, so you are suggesting that I cast the whole (tolower(selction[i])) to char by simply putting (char) in front. I do remember briefly talking about casting in an earlier chapter but I havent had to use it yet, I'll jump back into the book to read up on how exactly casting works.

thank you btw that worked perfectly. May I ask why you suggest '<' VS> "<=" ??

I should probably also tell you that the goal of (one part of this assignment) is to have a user input ANY OF THE THREE options cat,cop,cot in any variation of that (caps or not or combo of both).. we need to verify that the word is only one of those three and nothing else.

so my thought process was to to count all the way up to the end of what ever the user entered.. then insert some more loops that execute while selection = cat or cop...etc.. then if none of those are met ill fall out to an error message, so that is why I was thinking "<="

plz if you want, explain your view?

also thank you again for the quick and helpful response!
Last edited on
"hello" has a length of 5. count these: {0,1,2,3,4}. How many numbers do you see? the length() and the array index from zero trip up new coders a lot. It has 5 values. They are indexed 0,1,2,3,4.

to validate from a list of valid choices comparison is fine.
consider:
do
cin >> input;
input ... tolower... etc..
while(input != "cat" || input != "cop" || ... etc )

casting here is just to make the compiler accept your code. Read up on C++ style casts as said above. I used the C style because it is shorter and I am old and set in my ways. Do what Furry guy said and study that way, it is more correct than what I did.
Last edited on
Furry Guy wrote:
PLEASE learn to use code tags, they make reading and commenting on source code MUCH easier.

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

HINT: you can edit your post and add code tags.

Some formatting & indentation would not hurt either


thank you for the suggestions, i will be sure to learn these better for future posts, thank you.

jonnin wrote:
hello" has a length of 5. count these: {0,1,2,3,4}. How many numbers do you see? the length() and the array index from zero trip up new coders a lot. It has 5 values. They are indexed 0,1,2,3,4.

...while(input != "cat" || input != "cop" || ... etc )


That makes sense! I appreciate you taking the time to explain. I have been able to progress smoothly with the rest of the assignment. So thanks again for all of the help and tips!


A spot of history and philosophy of casting in C/C++

https://belaycpp.com/2021/10/14/history-of-c-the-genesis-of-casting/
Transforming a C++ string is easy with an algorithm and a lambda:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>

int main()
{
   std::string str { "This is A TeSt STrING" };

   std::cout << str << '\n';

   // https://en.cppreference.com/w/cpp/algorithm/transform
   // https://en.cppreference.com/w/cpp/string/byte/tolower
   std::transform(str.begin(), str.end(), str.begin(),
                  [] (unsigned char c) { return ::tolower(c); }); // lambda

   std::cout << str << '\n';

   std::transform(str.begin(), str.end(), str.begin(),
                  [] (unsigned char c) { return ::toupper(c); });

   std::cout << str << '\n';
}
This is A TeSt STrING
this is a test string
THIS IS A TEST STRING

You likely haven't learned about the <algorithm> library yet, a lot of useful stuff in there.
https://en.cppreference.com/w/cpp/algorithm

Probably haven't you been exposed to lambdas either. They are a really cool C++11 feature.
https://www.learncpp.com/cpp-tutorial/introduction-to-lambdas-anonymous-functions/
Furry Guy wrote:
Probably haven't you been exposed to lambdas either. They are a really cool C++11 feature.


No I have not been exposed to those yet! Although I did realize my teacher used the <algorithm> library in one of his lectures when we were building loops to check for the validation on various aspects of a users password.

I will be sure to look into that library here on C++ to see what all it contains. Thank you for the Helpful links!

I have been running into some more problems since the last post, It's still the same code. Just a different issue now. lol the assignment isn't due till the 30th.. so I am going to keep working on it.

BUT if I cant figure it out would you guys recommend that I start a new thread? or just continue posting here?
Just keep posting in this thread, starting a new thread is ultimately a time waster for those who reply.
Topic archived. No new replies allowed.