DarkSpy
DarkSpy

Reputation: 15

how to check if the string contains only numbers or word in c

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

Answers (4)

m0hithreddy
m0hithreddy

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

anastaciu
anastaciu

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:

Live demo

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

DevSolar
DevSolar

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

Edwin Buck
Edwin Buck

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

Related Questions