【问题标题】:Function to identify upper/lower case letters C识别大写/小写字母C的功能
【发布时间】:2016-04-28 13:08:32
【问题描述】:

我正在尝试创建一个函数,该函数将识别输入的第一个字母是大写还是小写,然后以相同的大小写(大写/小写)输出字符串的其余部分。

例如,"Hi there" 将变为 "HI THERE"

我不熟悉fgets。一旦我运行它,我可以输入并按 Enter 并且程序不会运行。我没有收到任何编译器错误。我相信我在 void shift 功能上出错了。

另外,我知道gets不推荐,fgets类似吗?还是使用scanf 更好?

#include <stdio.h>
#include <ctype.h>
void shift (char *my_string); // Function declaration

int main()
{
  char inputstring[50];

  printf("Enter a string\n");
  char *my_string = inputstring;
  shift(my_string); // Function
}

void shift (char *my_string) // Function definition
{
  int i =0;
  char ch;

  for(i=0; i<50; i++)
    fgets(my_string, 50, stdin);

  while(my_string[i])
  {
    if(ch>='A' && ch<= 'Z') // When first char is uppercase
    {
      putchar (toupper(my_string[i]));
      i++;
    }
    else if (ch>='a' && ch <= 'z') // When first char is lowercase
    {
      putchar(tolower(my_string[i]));
      i++
    }
  }
  return;
}

【问题讨论】:

标签: c string uppercase lowercase


【解决方案1】:

您无需拨打fgets() 五十次。它从stdin 中读取一行并将其写入my_string。看来您只想阅读一行,而不是五十行(并且只保留最后一行)。 50 是将读取和写入缓冲区的最大字符数(减一)。这个限制是为了防止缓冲区溢出。见fgets()

尝试删除fgets() 调用之前行中的for 循环。此外,您不需要main() 中的my_string。更正后的代码:

#include <stdio.h>
#include <ctype.h>
void shift (char *my_string);//function declaration

int main()
{
  char inputstring[50];

  printf("Enter a string\n");
  shift(inputstring);
}

void shift (char *my_string) //function definition
{
  int i;
  char ch;

  if ( fgets(my_string, 50, stdin) == NULL )
    return;

  ch = my_string[0];
  for ( i=0; my_string[i]; i++ )
  {
    if(ch>='A' && ch<= 'Z') //when first char is uppercase
    {
        putchar (toupper(my_string[i]));
    }
    else if (ch>='a' && ch <= 'z')//when first char is lowercase
    {
        putchar(tolower(my_string[i]));
    }
  }
  return;
}

编辑:添加了@thurizas 指出的ch 初始化。将 while 循环更改为 for 循环。根据@JonathanLeffler 的建议,添加了对fgets() 的返回值的检查。 (请参阅他关于缓冲区大小的评论。)

【讨论】:

  • 我看不到 ch 在您的代码中初始化的位置(关于 OP 代码的相同注释)。
  • 您应该在使用输入字符串之前检查来自fgets() 的返回状态。此外,如果您在按回车之前键入一行 140 个字符,则第一次调用 fgets(my_string, 50, stdin) 将返回前 49 个字符(加上一个空终止符)而没有任何换行符。第二次调用将返回接下来的 49 个字符,不带任何换行符。只有第三个调用(将返回 42 个字符加上换行符和空值)获得换行符。
  • 我是getline() 的粉丝,它使用 NULL 作为第一个参数,因此它会为您分配缓冲区,无论它需要多少。但是你必须在完成后自己free()。动态记忆似乎超出了原始问题的水平。
【解决方案2】:

所有 ASCII 字符均由 7 位表示。 (因此称为 7 位 ASCII)lower-caseupper-case 之间的唯一位差异是 bit-5(第六位)设置为小写和清除(未设置)为大写。这允许在小写和大写之间进行简单的按位转换(通过加/减 32 或直接翻转第 5 位。)

      +-- lowercase bit
      |
a = 01100001    A = 01000001
b = 01100010    B = 01000010
c = 01100011    C = 01000011
...

如果第一个字符是大写,则可以进行简单的测试和转换:

#include <stdio.h>

enum { MAXC = 50 };

char *shift (char *my_string);

int main (void)
{
    char inputstring[MAXC] = {0};;

    printf ("\n Enter a string: ");
    if (shift (inputstring))
        printf (" my_string is  : %s\n", inputstring);

    return 0;
}

char *shift (char *my_string)
{
    char *p;

    if (!(p = fgets (my_string, MAXC, stdin))) return NULL;

    if (*p == '\n') return NULL;   /* Enter only pressed  */

    if ('A' <= *p && *p <= 'Z')    /* test for upper case */
        for (; *p; p++)            /* convert lower/upper */
            if ('a' <= *p && *p <= 'z') *p &= ~(1 << 5);

    return my_string;
}

使用示例

$ ./bin/case_1st_to_upper

 Enter a string: this is my string
 my_string is  : this is my string

$ ./bin/case_1st_to_upper

 Enter a string: This is my string
 my_string is  : THIS IS MY STRING

【讨论】:

    【解决方案3】:
    • 这是您问题的另一种解决方案,

      #include <stdio.h>
      #include <ctype.h>
      void convertTo (char *string);
      
      int main()
      {
         char inputString[50];
      
         printf("Enter a string\n");
         convertTo(inputString);
      }
      
      void convertTo (char *string)
      {
         int i;
         char ch;
      
         gets(string);
      
         ch = string[0];
         for ( i=0; string[i]; i++ )
         {
            if(ch>='A' && ch<= 'Z')
            {
               if(string[i]>='a' && string[i]<= 'z')
                  string[i] = string[i] - 32;
            }
            else if (ch>='a' && ch <= 'z')
            {
               if(string[i]>='A' && string[i]<= 'Z')
                  string[i] = string[i] + 32;
            }
         }
         printf("%s\n", string);
         return;
      }
      

    【讨论】:

      猜你喜欢
      • 2019-02-15
      • 2018-12-22
      • 2015-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-04
      相关资源
      最近更新 更多