char ch;
do
{
printf("Digite aqui um caractere: ");
scanf(" %c", &ch);
} while ((ch < 'A' && ch > 'Z' ) || (ch < 'a' && ch > 'z') || ch != '.');
return ch;
I tried all sort of things on this condition and I can't make it happen. I want to return the value of "ch" when the input is [A-Z] or [a-z] or '.'.
In the condition of the loop
while ((ch < 'A' && ch > 'Z' ) || (ch < 'a' && ch > 'z') || ch != '.');
for example thus subexpression
(ch < 'A' && ch > 'Z' )
is always evaluates to logical false because a character can not be at the same time less than 'A'
and greater than 'Z'
.
To simplify the condition at first rewrite it for the case when the loop should be interrupted.
The loop is interrupted when
( ( 'A' <= ch && ch <= 'Z' ) || ( 'a' <= ch && ch <= 'z') || ( ch == '.' ));
Now write its negation
!( ( 'A' <= ch && ch <= 'Z' ) || ( 'a' <= ch && ch <= 'z') || ( ch == '.' ));
You will get
( !( 'A' <= ch && ch <= 'Z' ) && !( 'a' <= ch && ch <= 'z') && !( ch == '.' ));
It is the same as
( ( !('A' <= ch ) || !( ch <= 'Z' ) ) && ( !( 'a' <= ch ) || !(ch <= 'z' )) && ( ch != '.' ));
or
( ( ch < 'A' || ch > 'Z' ) && ( ch < 'a' || ch > 'z' ) && ( ch != '.' ));
So you will have
while ( ( ch < 'A' || ch > 'Z' ) && ( ch < 'a' || ch > 'z' ) && ( ch != '.' ));
Another approach is to use standard function tolower
or toupper
declared in the header <ctype.h>
to simplify the condition as for example
while ( ( toupper( ( unsigned char )ch ) < 'A' || toupper( unsigned char )ch ) > 'Z' ) && ( ch != '.' ));
Or according to the remarkable idea of @Gerhardh you can also write
while ( !isalpha( ( unsigned char )ch ) && ( ch != '.' ));