Reputation: 15
My teacher gave us code that Write a function declared as "int categorize(char *str)" which accepts a string as an input parameter and categorize the string. The function should return the category number as decribed below:
Category 1: If the string contains only capital letters (e.g. ABCDEF), the function should return 1.
Category 2: If the string contains only small letters (e.g. abcdef), the function should return 2.
Category 3: If the string contains only letters but no other symbols (e.g. ABCabc), the function should return 3.
Category 4: If the string contains only digits (e.g. 12345), the function should return 4.
Category 5: If the string contains both letters and digits but no other symbols (e.g. Hello123), the function should return 5.
Category 6: Otherwise, the function should return 6.
I write this but not working
#include<stdio.h>
#include<string.h>
// Write your categorize function here
int categorize(char *str) {
int x=0;
while(str[x]!= '\0'){
if((*str>='A'&&*str<='Z') && (*str>='a'&&*str<='z') && (*str>='0'&&*str<='9'))
return 5;
else if((*str>='A'&&*str<='Z') && (*str>='a'&&*str<='z'))
return 3;
if((*str>='A') && (*str<='Z'))
return 1;
else if((*str>='a')&&(*str<='z'))
return 2;
else if((*str>='0')&&(*str<='9'))
return 4;
x++;
}
return 6;
}
///////////////////////////////////////
// Test main()
// DO NOT MODIFY main()
// or your code will not be evaluated
int main() {
char str[100];
scanf("%s",str);
int c = categorize(str);
printf("%d\n",c);
return 0;
}
///////////////////////////////////////
Upvotes: 0
Views: 3664
Reputation: 1839
You can do this in O(n)
as follows:
#include <ctype.h>
#include <stdio.h>
int check_str(char* str)
{
int category = 0; // 0b001 -> Uper | 0b010 -> Lower | 0b100 -> Number
for ( ; *str != 0; str++) {
if (isupper(*str)) {
category |= 1;
}
else if (islower(*str)) {
category |= 2;
}
else if (isdigit(*str)) {
category |= 4;
}
else
return 6;
}
if (category == 1)
return 1;
if (category == 2)
return 2;
if (category == 3)
return 3;
if (category == 4)
return 4;
if (category == 7)
return 5;
return 6;
}
int main()
{
printf("%d\n", check_str("ABCDEF"));
printf("%d\n", check_str("abcdef"));
printf("%d\n", check_str("ABCabc"));
printf("%d\n", check_str("12345"));
printf("%d\n", check_str("Hello123"));
printf("%d\n", check_str("Hello World 123"));
return 0;
}
OUTPUT
1
2
3
4
5
6
EDIT
Since 0b...
is not portable, binary numbers are changed to their decimal equivalents
Upvotes: 2
Reputation: 23822
*str
this is a pointer to the first character of the string so along your cycle it only checks this first character.
Furthermore you are returning values before checking the entire string, you need to use flags and set them along the cycle for digits caps and small letters, and in the end return the values according to those flags.
There is the <ctype.h>
library which has functions like isalpha
and isdigit
and can make your job easier, for that I refer you to @DevSolar answer as a better method.
If you can't use it this is the way to go:
int categorize(char *str) {
int x = 0;
int is_digit, is_cap, is_small;
is_cap = is_digit = is_small = 0;
while (str[x] != '\0') {
if (!(str[x] >= 'a' && str[x] <= 'z') && !(str[x] >= 'A' && str[x] <= 'Z') && !(str[x] >= '0' && str[x] <= '9'))
return 6;
if (str[x] >= 'A' && str[x] <= 'Z' && !is_cap) //if there are caps
is_cap = 1;
if (str[x] >= '0' && str[x] <= '9' && !is_digit) //if there are digits
is_digit = 1;
if (str[x] >= 'a' && str[x] <= 'z' && !is_small) //if there are smalls
is_small = 1;
x++;
}
if ((is_small || is_cap) && is_digit){
return 5;
}
if(is_small && is_cap){
return 3;
}
if(is_digit){
return 4;
}
if(is_small){
return 2;
}
if(is_cap){
return 1;
}
return 6;
}
Note that this kind of character arithmetic works well in ASCII but fails in other character encodings like EBCDIC which don't have sequencial order for alphabetic characters.
Upvotes: 2
Reputation: 70333
The standard header <ctype.h>
literally has everything you are looking for:
Category 1 is if isupper()
is true for all characters.
Category 2 is if islower()
is true for all characters.
Category 3 is if isalpha()
is true for all characters.
Category 4 is if isdigit()
is true for all characters.
Category 5 is if isalnum()
is true for all characters.
A quick-and-dirty approach could just iterate through the input once for each of the above:
int categorize( char * str )
{
char * s;
for ( s = str; *s; ++s )
{
/* Need the cast to unsigned char here; negative values
are reserved for EOF!
*/
if ( ! isupper( (unsigned char)*s ) )
{
break;
}
}
if ( ! *s )
{
/* True if the loop ran its full course without breaking */
return 1;
}
/* Same for the other categories */
return 6;
}
Once you got this done, you could start getting funny with the logic, putting all the checks into one loop and keeping track of conditions met.
Upvotes: 1
Reputation: 70929
You seem to have a pretty good start for your project. You capture a String, and then categorize it.
Where you need to improve is the logic for categorization. I would start by making each of your categories into a function.
int isOnlyCapital(char* string)
might return 1
if the string is only comprised of capital letters, and 0
otherwise. The logic might look like
char* position = string;
while (position != '\0') {
if (*position < 'A' || *position > 'Z') {
return false;
}
position++;
}
return true;
Note that you can only return true if you managed to check all charaters with the above code, as you have looped over all characters until you hit the NULL character \0
.
With some work, you can modify the above loop to handle your other cases. That would make your logic for the overall top level look like.
if (isOnlyCapital(string)) return 1;
if (isOnlyLowercase(string)) return 2;
... and so on...
Upvotes: -2