Reputation: 21
so i am trying to ask the user for only capital letters and if they put in lower case letters or any other symbols or numbers i want to ask them for a new input. I am trying ASCII but i think im doing it wrong? please help me
#include <iostream>
#include <string>
using namespace std;
int main (){
string teams[100] = {};
int removeLast=0;
cout << "please enter ONLY capital letters, (TYPE 'done' to exit)\n";
for (int i=0;i<100;i++){
cin>> teams[i];
if (('A'>= teams[i] && 'Z'<= teams[i] )){ //problem is in this line
cout << "letter must be capital\n";
continue;
}
removeLast++;
if (teams[i] == "done") break;
}
cout << "this is the result you entered\n";
for (int m = 0; m < removeLast-1;m++ ){
cout << teams[m];
}
}
Upvotes: 1
Views: 4005
Reputation: 1145
Reinventing the wheel is never a good solution. Take a look at this:
https://en.cppreference.com/w/cpp/string/byte/isupper
and yes, there's also the problem you're using 100 strings.
Upvotes: 1
Reputation: 84579
Beyond your apparent problem of the impossibility of the comparison being both <= 'A'
and >= 'Z'
at the same time, you have fundamental problems with the types you declare in your program.
string teams[100] = {};
Declares an array of 100 strings, not a single string of 100-characters. This should be readily apparent in the compiler errors, e.g.
strarr.cpp:15:17: error: no match for ‘operator>=’ (operand types are ‘char’
and ‘std::string {aka std::basic_string<char>}’)
if (('A'>= teams[i] && 'Z'<= teams[i] )){ //problem is in this line
If you did intend to have a maximum of 100-teams entered, (which by "teams"
being plural would at least linguistically seem to be the case), then you need to change your comparison to compare the first-character in each string, with teams[i][0]
Further, you cannot use a for
loop to automatically increment removelast
. Why? What happens if it is not a captial letter? (answer: it is stored in string[i]
and you increment removelast
anyway). Instead, just use a simple while
loop and an index as a counter and to protect your array bounds only increment the index if the team begins with an upper case letter, e.g. (using ndx
for index, and using isupper()
to check the case)
while (ndx < 100) { /* loop until max index or done */
if (!(cin >> teams[ndx])) { /* always validate your input */
cerr << "input error or user canceled.\n";
break;
}
if (teams[ndx] == "done") /* check exit condition */
break;
else if (isupper (teams[ndx][0])) { /* use isupper() */
ndx++; /* only increment if condition satisfied */
}
else /* handle not a captital */
cout << " error: letter must be capital\n";
}
Now it is unclear whether you want to force all letters to be capital letters or just the first letter. If you want all letters upper case, then you can simply include a flag and loop over all charactes entered setting the flag to false
if not all characters are uppercase. For example, you could do:
while (ndx < 100) { /* loop until max index or done */
bool allupper = true; /* flag indicating all uppercase */
if (!(cin >> teams[ndx])) { /* always validate your input */
cerr << "input error or user canceled.\n";
break;
}
if (teams[ndx] == "done") /* check exit condition */
break;
for (auto& c : teams[ndx]) /* simple loop checking each char */
if (!isupper(c) ) /* on failed test */
allupper = false; /* set flag false */
if (allupper) /* validate all uppercase characters */
ndx++; /* only increment if condition satisfied */
else /* handle not a captital */
cout << " error: letter must be capital\n";
}
Hopefully that addresses your issues. Note also, for counts, generally a size_t
type is preferred over int
(you wouldn't have a negative index). A working example of the code checking all characters for uppercase would be:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main (void) {
string teams[100] = {};
size_t ndx = 0;
cout << "please enter ONLY capital letters, (TYPE 'done' to exit)\n";
while (ndx < 100) { /* loop until max index or done */
bool allupper = true; /* flag indicating all uppercase */
if (!(cin >> teams[ndx])) { /* always validate your input */
cerr << "input error or user canceled.\n";
break;
}
if (teams[ndx] == "done") /* check exit condition */
break;
for (auto& c : teams[ndx]) /* simple loop checking each char */
if (!isupper(c) ) /* on failed test */
allupper = false; /* set flag false */
if (allupper) /* validate all uppercase characters */
ndx++; /* only increment if condition satisfied */
else /* handle not a captital */
cout << " error: letter must be capital\n";
}
cout << "this is the result you entered\n";
for (size_t m = 0; m < ndx; m++) {
cout << teams[m] << '\n';
}
}
(note: while it is perfectly OK to use an array of string
, you would generally want to use a container, such as a vector
of string
, e.g. vector<string>
to let the container manage the number of strings you have as needed, and remove your responsibility for enforcing the array bounds)
Example Use/Output
$ ./bin/strarr
please enter ONLY capital letters, (TYPE 'done' to exit)
DOLPHINS
SAINTS
STEELeRS
error: letter must be capital
STEELERS
VIKINGS
done
this is the result you entered
DOLPHINS
SAINTS
STEELERS
VIKINGS
For an example checking only the first character, just substitute in the first block of code above. Let me know if you have further questions.
Upvotes: 1
Reputation: 669
string teams[100] = {};
if (('A'>= teams[i] && 'Z'<= teams[i] )){ //problem is in this line
The issue is how you are performing your comparison to a std::string data type.
teams[i] could equal "BaNANAS", and you are comparing it to a single charecter. For the check you describe, you need to iterate through the entire string and check it for your criteria:
for (char &c: teams[i]) {
if (c < 'A' || c > 'Z') {
// There is an error
}
}
// If it gets here with no error, the input matches your desired criteria
Upvotes: 1