Is there a way to put multiple ranges in one if statement - c

I'm new at c and stack overflow please forgive my amateur mistakes if there are some...
I'm trying to accept digits between 0 and 9, uppercase letters and lowercase letters in my code. So ascii codes between 48-57 or 65-90 or 98-122. There is also a previous part of the code containing the menu. I did not include it for brevity.
This is the first thing i tried:
int main()
{
char n;
printf("\n\nWhich code will you use?: ");
scanf("%c",&n);
if (n<=57 && n>=57 || n<=65 && n>=95 || n<=98 && n>= 122)
printf("Binary equivalent..");
/*there is supposed to be a whole another
section here.. however i haven't completed
that yet. I put a print statement to make
sure if the if statement would work...*/
else
printf("Wrong input..");
}
...
This gives the result of "wrong input" whatever i input ( I inputed c, a and 4).
The second thing i tried was to put parenthesis:
...
if ((n<=48 && n>=57 )||( n<=65 && n>=95 )||( n<=98 && n>= 122))
...
Then i tried changing the "%c" to a "%d" which didn't change anything either.
...
printf("\n\nWhich code will you use?: ");
scanf("%d",&n);
...
The only thing that worked was to seperate each relation into three different if statements. However i'm going to be writing the same thing in every if statement which i feel like makes my code unnecessarily long...

You messed up the relations direction, and you could also use the character literals. Try this
if ((n >= '0' && n <= '9') || (n >= 'A' && n <= 'Z' ) || (n >= 'a' && n <= 'z'))

ASCII values
Digits (0-9): 48-57
Uppercase letters (A-Z): 65-90
Lowercase letters (a-z): 97-122
Conditions
c >= 48 && c <= 57: true if c is a digit
c >= 65 && c <= 90: true if c is an uppercase letter
c >= 97 && c <= 122: true if c is a lowercase letter
(c >= 48 && c <= 57) || (c >= 65 && c <= 90) || (c >= 97 && c <= 122): true if c is alphanumeric (a letter or a digit)
But it is much easier to use 'a' instead of 97, because you don't need to learn the whole ASCII table by heart that way.
Notes
n<=48 && n>=57 will always be false. If you pause for a second, you'll realise that no number (in the ASCII table or not) can be less than 48 and greater than 57 at the same time.

Related

A function that detects whether a string contains an uppercase letter or not, and if so, converts it to a lowercase letter

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?
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>.
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.

plus alphabet kind of

first of all, i'm a college freshman. i'd like to help my college task? i would really appreciate if you help my task.
And this task uses C language.
first i need to get two inputs (using scanf; one is alphabet like a or A and the other is arabic number like 1, 2)
and i need to add number on alphabet
ex) if i put
A 3
and the computer indicates D
here is the point, if i put Y 4 i need to get 'C' (using ASCII code and % )
the lower part is what i've tried for this task
int input;
char eng;
scanf("%c %d", &eng, &input);
if (eng >= 'a' && eng <= 'z') {
eng = (eng + input) % ('z' - 'a') + eng -1;
}
it compiles but when i put y 4 it results x however i need c .
You want this:
eng = ((eng - 'a') + input) % ('z' - 'a' + 1) +'a'
(eng - 'a') transforms your input from ['a'..'z'] into the domain [0..25].
+ input adds the offset
% ('z' - 'a' + 1) does the modulo
and finally + 'a' transforms the domain [0..25] back into ['a'..'z']

Why multiple if works and if else does not it this case [duplicate]

This question already has answers here:
Chaining multiple greater than/less than operators
(6 answers)
Two '==' equality operators in same 'if' condition are not working as intended
(4 answers)
Math-like chaining of the comparison operator - as in, "if ( (5<j<=1) )" [duplicate]
(4 answers)
Closed 3 years ago.
I'm learning C and I've came around a strange problem. I think I understand the difference between multiple ifs and else-if statement, but I simply can not understand the difference in behavior this time. If I delete the else keyword it works as intended, but with else on it does not.
The code is about counting of occurrences of each letter without differentiating lower case or upper case (so 'a' and 'A' both counts as 1 occurrence for letter 'a').
I've tried omitting braces where I could but nothings changed so I've left them in to avoid caveats.
while ((c = getchar()) != EOF)
{
if ('A' < c < 'Z')
{
++array[c - 'A'];
}
else if ('a' < c < 'z')
{
++array[c - 'a'];
}
}
When I type in 'a' then the array is not being incremented, but if I delete the else statement thus switching to a multiple if situation, it works as intended. Letter 'A' updates the array nicely in both cases.
Could you please help me understand the difference in behavior in this case?
What we need to know:
The result of < comparison is an int with value 1 for true and 0 for false. It's like the result of 1 + 3 is int with value 4, the same way the result of 1 < 3 is an int with value 1.
Operator < has associativity Left to Right. That means that in 1 < 2 < 3 it will be parsed as (1 < 2) < 3 - ie. first will be 1 < 2 calculated, then the result will be < 3 compared with 3.
So:
'A' < c < 'Z'
is interpreted as
('A' < c) < 'Z'
The result of 'A' < c is either 1 or 0. When 'A' is lower then c, then it becomes:
1 < 'Z'
otherwise it becomes:
0 < 'Z'
Both cases are true, so the comparison is always true.
If you want to check if a number is a letter between A and Z including the letters A and Z, you can:
if ('A' <= c && c <= 'Z') {
or #include <ctype.h> and use isupper function:
if (isupper(c)) {
try
while ((c = getchar()) != EOF)
{
if ('A' <= c && c <= 'Z')
{
++array[c - 'A'];
}
else if ('a' <= c && c <= 'z')
{
++array[c - 'a'];
}
}
'a'<c<'z' is computed not like a mathmatical expression, first 'a' < c is evaluated to True or False then that value (converted to 0 or 1 probably) is compared to 'z', so it is not doing what you are expecting it to.
The relational operators like < take two operands and returns 1 if the first operand is smaller than the second, otherwise 0.
Thus 'A' < c gives a result of 1 or 0, and then (since < operators associate left-to-right) you compare the value 1 or 0 with the ASCII value of 'Z', which is nonsense.
Correct code for checking if a variable is inside an interval is
if ( (c >= 'A') && (c <= 'Z') )
Also make sure c is int and not char, because getchar actually returns int, and to compare against EOF you will need to use int.

How can I change capital letters to small letters and vice versa in strings, without using string commands and acii code

I have to write the function that deletes every char from the text that isn't a number,changes first letter of every word to capital letter and changes rest letters to small letters.
The problem is that :
I can't use ctype, stdlib and string library
I can use only scanf when I want to input
I can't use [] operator except for the array declaration
I can't use digits except for 0 and 1
Normally it would be easy but with those conditions, I have no idea how to do it. I'm new into strings, don't be harsh :).
Maybe try to make some macros like this:
#define IS_UPPER(c) ( (c) >= 'A' && (c) <= 'Z' )
#define IS_LOWER(c) ( (c) >= 'a' && (c) <= 'z')
#define TO_UPPER(c) ( (c) -= ('a' - 'A'))
#define TO_LOWER(c) ( (c) += ('a' - 'A'))
#define IS_ALPHA(c) ( IS_UPPER(c) || IS_LOWER(c) )
And see if you can make something work
void homework(char * txt)
{
while(*txt != NUL)
{
/* do some stuff */
txt++;
}
}

Wrong answer while Changing the upper case letters to lower case and vice versa

I can't identify the mistake. In place of a, A has to be printed but some other letter is printing. Same in the case of other letters. Please help to find the mistake.
#include<stdio.h>
#include<conio.h>
#include<string.h>
int main()
{
char m[20];
int i;
printf("Enter any string:");
gets(m);
for(i=0;i<=strlen(m);i++)
{
if(m[i]>=97&&m[i]<=122)
m[i]=m[i]-26;
else
m[i]=m[i]+26;
}
printf("%s\n",m);
return 0;
}
Change the loop the following way
for(i=0; i < strlen(m); i++ )
^^^
Otherwise you overwrite the terminating zero.
And instead of magic numbers 97 and 122 it is better to use letters 'A' and 'Z'.
For example
if ( m[i] >= 'A' && m[i] <= 'Z' )
Also it seems this statement
m[i]=m[i]-26;
is wrong
I think you mean the following
if ( m[i] >= 'A' && m[i] <= 'Z' )
m[i] = m[i] + 'a' - 'A' ;
else if ( m[i] >= 'a' && m[i] <= 'z' )
m[i] = m[i] - 'a' + 'A' ;
Take into account that there are standard functions isupper and islower and correspondingly toupper and tolower declared in header <ctype.h>
Also function gets is not supported any more by the C Standard because it is unsafe. I advice to use fgets instead.
The value will be 32 not 26.
if(m[i]>=97&&m[i]<=122)
m[i]=m[i]-32;
else
m[i]=m[i]+32;
Better to use for checking isupper and islower. Then change by tolower and toupper. Then you don't have to think about ASCII value.
if(isupper(m[i]))
{
m[i]=tolower(m[i]);
}
else
{
m[i]=toupper(m[i]);
}
Just change 26 to 32, since between the uppercase letters and lowercase characters, you have some other ascii values like [ \ ] ^ _ ...
Here's an ascii table for you to check for yourself
EDIT: Also, when you fix that, you might want to change your termination condition (you'll probably get an OutOfBounds Exception if you don't) to i<strlen(m), as you're working with a zero-based system (i,e starts with 0 and ends with strlen(m)-1, vs starting with 1 and ending with strlen(m)).
Your conversion of an uppercase letter to a lower case letter is wrong.The ascii difference is 32 and not 26.
Also you should run your loop till strlen(m)-1 as the characters are stored from zero index.
for(i=0;i<strlen(m);i++)
{
if(m[i]>=97&&m[i]<=122)
m[i]=m[i]-32;//changing lower case to upper requires subtraction of 32
else
m[i]=m[i]+32;
}

Resources