Valid Invalid statements

Given Question:
Output "Valid" if input doesn't start with a letter. Otherwise, output "Invalid".

My Issue:
Can only ouput "invalid" statements for words that begin with letters from the alphabet but CANNOT output "valid" statements for words that begin with nonalphabetic characters(eg. 7961, $zt93v, and 51903784).

#include <iostream>
using namespace std;

int main() {
bool passwordValid;
string keyString;

cin >> keyString;
/// restricted from editing above this

while (!(isalpha(keyString.at(0)) ) ){
passwordValid == true;

/// restricted from editing below this

if (passwordValid) {
cout << "Valid" << endl;
}
else {
cout << "Invalid" << endl;
}

return 0;
}
Assignment is =, not ==.

Please use code tags. Then we can refer to your line number.
Also, why the while statement, it could be just an if statement.
1
2
3
4
5
6
7
8
9
#include <iostream>
#include <string>

int main() {
	std::string keyString;

	std::cin >> keyString;
	std::cout << ((keyString.empty() || isalpha(keyString[0])) ? "in" : "") << "valid\n";
}

#include <cctype>

and then:
keyString.empty() || std::isalpha( static_cast<unsigned char>( keyString[0] ) ? ...

the behavior of std::isalpha is undefined if the argument's value is neither representable as unsigned char nor equal to EOF. To use these functions safely with plain chars (or signed chars), the argument should first be converted to unsigned char https://en.cppreference.com/w/cpp/string/byte/isalpha
Yeah - I know. I was in a hurry. It worked with VS. No excuse though.

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <string>
#include <cctype>

int main() {
	std::string keyString;

	std::cin >> keyString;
	std::cout << ((keyString.empty() || std::isalpha(static_cast<unsigned char>(keyString[0]))) ? "in" : "") << "valid\n";
}

Last edited on
std::isalpha( static_cast<unsigned char>( keyString[0] )

To be blunt, that is an (unnecessary) abomination.

To use those functions "safely" in these excessive terms the keyboard device (or any other input device) would have to be using the same locale as whoever compiled the program and you would have to have consensus as to which letters would return isalpha as non-zero (true).

For any reasonable input from a standard keyboard a cast is unnecessary pedantry. For any ASCII input (int = 0 to 127) - all that isalpha seems to be unambiguously defined for - the cast is unnecessary.
Last edited on
> For any reasonable input from a standard keyboard a cast is unnecessary pedantry.

Use std::isupper from <locale>; it does not require a cast.
Or program in a language (eg. Java) which by and large steers clear of undefined behaviour.

In C++, these are the options:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <cctype>
#include <locale>

int main()
{
    char c = 0 ;
    std::cin >> c ;

    [[maybe_unused]] bool a = std::isupper( static_cast< unsigned char >(c) ) ; // alpha as per the current C locale
    [[maybe_unused]] bool b = std::isupper( c, std::cin.getloc() ) ; // alpha as per the current stdin input locale
    [[maybe_unused]] bool d = std::isupper( c, std::locale::classic() ) ; // alpha as per the current C locale
    [[maybe_unused]] bool e = std::isupper( c, std::locale() ) ; // alpha as per the global C++ locale
    [[maybe_unused]] bool f = std::isupper(c) ; // potential undefined behaviour
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <cctype>
#include <limits>

int main()
{
   int i1 = std::numeric_limits<char>::min();
   int i2 = std::numeric_limits<char>::max();
   
   std::cout << "char range " << i1 << " to " << i2 << '\n';
   
   for ( int i = i1; i <= i2; i++ )
   {
//    char c = i;
//    unsigned char u = c;
      char c = static_cast<char>( i );
      unsigned char u = static_cast<unsigned char>( c );

      std::cout << i << '\t' << c << '\t' << u << '\t' << std::isalpha( c ) << '\t' << std::isalpha( u ) << '\n';
   }
}




"Potential undefined behaviour" can be taken to ridiculous extremes.

For example,
int i = 123456;
would be "potential undefined behaviour" because the C++ standard only requires int to have a minimum range -32767 to 32767.

However, I don't think anyone would baulk at writing int i = 123456;
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
> For example,
> int i = 123456;
> would be "potential undefined behaviour" because ...

No. Narrowing conversions do not engender undefined behaviour.
Enable warnings, and the compiler can help you detect loss of information owing to narrowing.

1
2
3
4
5
6
7
8
int main()
{
    // *** warning: implicit conversion from 'long long' to 'int' changes value from 123456789087654321 to ...
    [[maybe_unused]] int i = 123456789087654321 ;

    // *** warning: implicit conversion from 'int' to 'char' changes value from 123456 to ...
    [[maybe_unused]] char c = 123456 ;
}

http://coliru.stacked-crooked.com/a/f26226e93c5fba17
Topic archived. No new replies allowed.