The following function works fine if the entire string consists of uppercase letters only, but does not for a string which consists of other characters too, such as "A man, a plan, a canal: Panama". In this case, every element is changed.
void UppercaseToLowercase(char arr[], int size)
{
for (int i = 0; i < size - 1; i ) // i < size - 1 since last element is '\0'
{
if (65 <= arr[i] <= 90) // ASCII values for uppercase letters
arr[i] = 32; // ASCII values for lowercase letters
}
}
How can this be corrected?
CodePudding user response:
65 <= arr[i] <= 90
does not test whether arr[i]
is between 65 and 90. Its grammatical structure is (65 <= arr[i]) <= 90
. This means that first 65 <= arr[i]
is evaluated. If it is true, the resulting value is 1. If it is false, the resulting value is 0. Then this result, 0 or 1, is compared to 90
, as if it were 0 <= 90
or 1 <= 90
. Both of these are true, so the result is always true.
The test should be written as 65 <= arr[i] && arr[i] <= 90
. The grammatical structure of this is (65 <= arr[i]) && (arr[i] <= 90)
. Each comparison is evaluated separately, and then their results are combined with &&
.
Additionally, character constants should be used instead of numeric constants. The test can be written 'A' <= arr[i] && arr[i] <= Z'
, which makes its intent and meaning clearer. Similarly, arr[i] = 32
should be written as arr[i] = 'a' - 'A'
. Then this code will work for any character set in which the codes for the uppercase letters are consecutive from “A” to “Z” and the codes for the lowercase letters are also consecutive.
There are character sets in which they are not consecutive, and code like this should not be used for fully portable support. I presume this is for a school exercise, in which case it is okay. However, fully portable code should use the isupper
and tolower
functions declared in <ctype.h>
.
CodePudding user response:
The issue you are having is in the logic of your if statement. Instead of
if (65 <= arr[i] <= 90)
A proper logical test for multiple conditions such as this would need to include the && conjunction. With what you are attempting to test, the comparison test would be as follows.
if (65 <= arr[i] && arr[i] <= 90) // ASCII values for uppercase letters
When testing that out with a word such as "Panama" following was the result in a test program built to call your function.
@Dev:~/C_Programs/Console/CaseCheck/bin/Release$ ./CaseCheck
Enter a word: Panama
Before: Panama
After: panama
The take-away from this issue is be cognizant of developing logic that have tests with multiple conditions that might require the && (and) conjunction or the || (or) conjunction.
Give that a try to see if it meets the spirit of your project.