【问题标题】:how to check if the string contains only numbers or word in c如何检查字符串是否仅包含c中的数字或单词
【发布时间】:2020-06-22 14:04:20
【问题描述】:

我的老师给了我们编写一个声明为“int categorize(char *str)”的函数的代码,该函数接受一个字符串作为输入参数并对字符串进行分类。该函数应返回如下所述的类别编号:

类别 1:如果字符串仅包含大写字母(例如 ABCDEF),则函数应返回 1。

类别 2:如果字符串仅包含小写字母(例如 abcdef),则函数应返回 2。

类别 3:如果字符串只包含字母而没有其他符号(例如 ABCabc),则函数应返回 3。

类别 4:如果字符串仅包含数字(例如 12345),则函数应返回 4。

类别 5:如果字符串包含字母和数字但没有其他符号(例如 Hello123),则函数应返回 5。

第 6 类:否则,该函数应返回 6。

我写了这个但不工作

#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;
 }
///////////////////////////////////////

【问题讨论】:

    标签: c arrays string pointers


    【解决方案1】:

    您可以在O(n) 中执行此操作,如下所示:

    #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;
    
    }
    

    输出

    1
    2
    3
    4
    5
    6
    

    编辑

    由于0b... 不可移植,因此二进制数被更改为它们的十进制等值

    【讨论】:

    • @DevSolar 真的!?我以前使用过它,即使现在它也可以编译并运行良好。如何用 C 写二进制数?
    • 是的,我查过了。 your 链接说,这是一个非标准扩展。 ;-)
    • @DevSolar 在这片狂野的森林里有很多我不知道的东西(^^) 是的,改成十进制对应。
    【解决方案2】:

    *str 这是一个指向字符串第一个字符的指针,所以在你的循环中它只检查第一个字符。

    此外,您在检查整个字符串之前返回值,您需要使用标志并沿着数字大写字母和小写字母的循环设置它们,最后根据这些标志返回值。

    &lt;ctype.h&gt; 库具有 isalphaisdigit 等功能,可以让您的工作更轻松,因为我建议您使用 @DevSolar answer 作为更好的方法。

    如果你不能使用它,这是要走的路:

    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;
    }
    

    请注意,这种字符运算在 ASCII 中运行良好,但在其他字符编码(如 EBCDIC)中失败,这些编码没有字母字符的顺序。

    【讨论】:

    • 我看到了字符算术,我哭了。
    • @DevSolar,这是一个评估,可能 OP 无法使用库函数。
    • 除了我坚决拒绝接受这种脑残的限制,而教师实际上应该教授鼓励使用标准库,&gt;= 'a'/就语言标准而言,&lt;= 'z' 实际上格式不正确,即使 非基本字符集发挥作用(因为存在 EBCDIC)。并且 OP 正在使用 &lt;string.h&gt;&lt;stdio.h&gt;,所以......让我们不要开始假设 hamstrung 环境,而是展示我们能做到的最好的。
    • @DevSolar,我有很多问题,包括在考试中,使用字符算术,重点是教它是如何完成的,我添加了免责声明以澄清编码问题。
    • 撤回了反对票。尽管我仍然认为“ASCII”以“大多数人使用的”的方式被提及是不幸的,但当我们实际使用的(即使我们没有使用完整的 Unicode)是 ISO-8859-15、CP-1252 或类似,A-Z 范围也不能说明全部真相。
    【解决方案3】:

    标准标题&lt;ctype.h&gt; 字面上包含您要查找的所有内容:

    • 类别 1isupper() 是否适用于所有字符。

    • 类别 2islower() 是否适用于所有字符。

    • 类别 3isalpha() 是否适用于所有字符。

    • 类别 4isdigit() 是否适用于所有字符。

    • 类别 5isalnum() 是否适用于所有字符。

    一种快速而简单的方法可以只对上述每个输入迭代一次:

    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;
    }
    

    完成此操作后,您可以开始对逻辑变得有趣,将所有检查放入一个循环并跟踪满足的条件。

    【讨论】:

      【解决方案4】:

      您的项目似乎有了一个很好的开始。您捕获一个字符串,然后对其进行分类。

      您需要改进的是分类逻辑。我将首先将您的每个类别变成一个函数。

      int isOnlyCapital(char* string)
      

      如果字符串仅由大写字母组成,则可能返回1,否则返回0。逻辑可能看起来像

          char* position = string;
          while (position != '\0') {
            if (*position < 'A' || *position > 'Z') {
              return false;
            }
            position++;
          }
          return true;
      

      请注意,如果您设法使用上述代码检查了所有字符,则只能返回 true,因为您已遍历所有字符,直到您遇到 NULL 字符 \0

      通过一些工作,您可以修改上述循环来处理您的其他情况。这将使您的整体顶层逻辑看起来像。

       if (isOnlyCapital(string)) return 1;
       if (isOnlyLowercase(string)) return 2;
       ... and so on...
      

      【讨论】:

      • 这会多次扫描字符串,这不是一个好习惯。我建议扫描字符串一次,计算适合每个类别的字符数。我也认为 isalpha(3) 库例程会很有用。
      • @mpez0 如果“扫描”是指捕获该行,那么它只会捕获一个。如果“扫描”是指解析行,是的,它会执行多次传递。请注意,与磁盘相比,CPU 速度非常快,一般来说 IO 也是如此。因此,简单的方法通常比复杂的一次性方法更容易处理。是的,我本可以返回一组 {captial, numeric, lowercase, space, etc} 但这是一个新的 C 程序员,在他们获得一些经验之前,他们可能不会用这种方法做得很好。跨度>
      • 我看到了字符算术,我哭了。
      • @DevSolar 我同意,它甚至不符合 UTF(anything) 标准。但是,在学习 C 时,正如这个人所做的那样,UTF 需要退居二线,直到该人学习该语言。
      • EDCDIC 存在,非 ASCII-7 字符也存在。 “ö”是小写字母,“ß”或“å”也是如此。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-25
      • 2012-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-19
      相关资源
      最近更新 更多