zoukankan      html  css  js  c++  java
  • C语言编程题目(1)字符串格式化操作 手机键盘次数统计

    题目如下:

    本来遇到一些问题,还好都解决了。这里记录一下:

    0x01 回顾gets、fgets、scanf函数的使用和区别

     1 #include <stdio.h>
     2 #include <string.h>
     3 
     4 int main(void)
     5 {
     6     char buffer[201];
     7     char *ptr;
     8     ptr = gets(buffer);
     9     printf("buffer length = %d, or %d, buffer = '%s',ptr = '%s'.
    ",strlen(buffer),strlen(ptr),buffer,ptr);
    10 return 0; 11 }

               

      我们输入的字符串为'hello world!',共12个字符,完整的显示出来;值得注意的是gets函数返回值是一个字符串指针,指向输入的字符串,也就是buffer数组的首地址。

      然而可能会出现这样一种问题,gets(buffer);的buffer数组大小有限,但是从控制台输入的信息可能会超过这个数组大小,这个函数就会轻易的导致缓冲区溢出问题且难以避免。因此在系统安全性更高的Linux gcc环境下编译,带有gets函数的程序被编译时会出现一些警告,甚至出错;它会提示你使用更安全的fgets函数来替代gets函数减少意料之外的错误。

    1 int main(void)
    2 {
    3     char buffer[65];
    4     char *ptr;
    5     ptr = fgets(buffer,sizeof(buffer),stdin);
    6     printf("buffer length = %d, or %d, buffer = '%s',ptr = '%s'.
    ",strlen(buffer),strlen(ptr),buffer,ptr);
    7     return 0;
    8 }

               

       我们输入的字符串为'hello world!',明明只有12个字符,却显示字符串长度竟然为13,打印字符串竟然意外换行(单引号另起一行可以看出),可见fgets函数和gets函数区别在于fgets可以读取最后的换行符为结尾使得buffer = “hello world! ”,长度包括 所占的一个字符。

      其次,值得注意的是fgets函数控制输入字符的最大数目(fgets接受的第二个参数是输入字符的最大数目),这和gets函数相比具有较高的安全性,避免了缓冲区溢出的可能性:因为我把参数2设为sizeof(buffer)就完全不用担心输入长度超过buffer大小带来的溢出风险。而且,fgets函数第三个参数指定了从哪里读入一行字符(到换行符 结束读),可以从打开的文件指针fp读出一行,也可以使用stdin从控制端输入。

    1 int main()
    2 {
    3     char buffer[65];
    4     scanf("%s",buffer);
    5     printf("buffer length = %d ,buffer = '%s'.
    ",strlen(buffer),buffer);
    6     return 0;
    7 }    

                  

      能看出来,scanf函数读取字符串时候遇到空格或者换行符就停止读取(字符串末尾不包含换行符或最后的空格),依次不适合用来读取带空格的长字符串。但是当已知输入字符串每行格式为固定形式的时候,可以定义好scanf格式化参数来分别接收分隔开的参数。例如学籍信息输入学生信息记录为:生姓名 学号 性别 专业 班级 ,拿上个例子继续优化scanf如下:

    1 int main()
    2 {
    3     char buffer[65],buffer2[65];
    4     scanf("%s %s",buffer,buffer2);
    5     printf("buffer length = %d ,buffer2 length = %d ,buffer = '%s',buffer2 = '%s'.
    ",strlen(buffer),strlen(buffer2),buffer,buffer2);
    6     return 0;
    7 }

              

    0x02 题目的解

      先定义两个函数,一个函数根据输入的字符,对照键盘,得到打印字符需要的次数。另一个函数接受字符串参数,每个字符都调用第一个函数得到数字,值加和并返回直到末尾字符 '#' 。

     1 int char_conv(char c)
     2 {
     3     if(c == 'a'||c == 'd'||c == 'g'||c == 'j'|| c == 'm'||c == 'p'||c == 't'||c == 'w'||c == ' ')
     4         return 1;
     5     else if(c == 'b'||c == 'e'||c == 'h'||c == 'k'||c == 'n'||c == 'q'||c == 'u'||c == 'x')
     6         return 2;
     7     else if(c == 'c'||c == 'f'||c == 'i'||c == 'l'||c == 'o'||c == 'r'||c == 'v'||c == 'y')
     8         return 3;
     9     else if(c == 's'||c == 'z')
    10         return 4;
    11     else
    12         return 0;
    13 }
    14 
    15 int string_conv(const char *src , int length)
    16 {
    17     char temp='';
    18     int index = 0,mark=0;
    19     while(index < length)
    20     {
    21         temp = src[index];
    22         if(temp == '#')
    23             break;
    24         mark += char_conv(temp);
    25         index++;
    26     }
    27     return mark;
    28 }

      其次,确定主函数结构,使用gets函数接受字符串,并保存指针地址为ptr,调用已定义的函数计算出每个字符串的键盘敲击次数存入数组array;最后遍历array并打印:

     1 int main()
     2 {
     3     int N=0,i=0;
     4     char buffer[201],*ptr;
     5     int array[10]; //假设最多输出10个字符串
     6 
     7 
     8     scanf("%d",&N);
     9     getchar();     //这行出乎人意料的重要,你可以注释掉这一行看看执行效果……
    10     for(i=0;i<N;i++)
    11     {    
    12         ptr = gets(buffer);
    13         array[i] = string_conv(ptr,strlen(buffer));        
    14         memset(buffer,0,sizeof(buffer));
    15     }
    16     i = 0;
    17     while(i<N)
    18     {
    19         printf("%d
    ",array[i]);
    20         i++;
    21     }
    22     return 0;
    23 }

      运行结果:

              

  • 相关阅读:
    10.2 处理大集合
    观察者模式——出版者与订阅者
    phonegap(cordova) 自己定义插件代码篇(五)----android ,iOS 集成微信登陆
    另一鲜为人知的单例写法-ThreadLocal
    Spring MVC中Controller如何将数据返回给页面
    IntelliJ IDEA安装主题详细步骤
    oracle导出dmp文件的2种方法
    Oracle导出表(即DMP文件)的两种方法
    Spring MVC 实现文件的上传和下载
    压力测试 JMeter3.3
  • 原文地址:https://www.cnblogs.com/Higgerw/p/11422220.html
Copyright © 2011-2022 走看看