第四课课件:/Files/furaibo/04程序设计基础-Cpp程序结构.ppt
关于变量的作用域、存储类别,请参照课本第115页至126页。
下面是一个非常好的模块化的例子,来自以下教材。
苏小红等,C语言大学使用教程(第2版),电子工业出版社
特别推荐,值得一读。该例子如下:
* 大家都知道,用scanf( )可以读入用户输入的整数或浮点数。但是在输入时,它并不限制字符类型。
在输入整数时,如果用户输入了字母或符号,scanf( )将报错,导致程序终止。
* 如果设计一个模块,限制在输入整数和浮点数时只可以输入合法的数字、正负号和小数点。
其余的字符都被忽略,并让计算机响铃警告,将是非常便利的。
这个模块的名字起名为getNum. 他提供了2个外部函数 getInt()和getFloat(),
和一个全局变量getNumError。每次调用外部函数之后可以检查getNumError,非0即出错。
getNum模块充分利用了函数调用,通过static修饰符,定义了getInput, hasDot()和isValidChar()等三个模块内部函数。
同样定义了两个模块内部全局变量buffer和pos。
程序代码如下:
头文件:getNum.h
1 extern int getNumError; // 声明外部变量
2
3 int getInt(void);
4 float getFloat(void);
2
3 int getInt(void);
4 float getFloat(void);
代码文件:getNum.cpp
代码
1 #include "getNum.h"
2 #include <stdlib.h>
3 #include <conio.h>
4 #include <stdio.h>
5
6 #define BUFFER_SIZE 32 // 输入缓冲区大小
7 #define INT 1 // 输入类型,整数
8 #define FLOAT 2 // 输入类型,浮点数
9
10 ////// 全局变量 //////
11 int getNumError = 0;
12 ////// 模块全局变量 //////
13 static int inputType; // 输入类型
14 static char buffer[BUFFER_SIZE]; // 输入缓冲区
15 static int pos = 0; // buffer中有效数据的末尾位置 + 1
16
17 ///// 模块内部函数,共享输入缓冲区 //////
18 static char* getInput(void);
19 static int isValidChar(char c);
20 static int hasDot(void);
21
22 /**
23 函数功能:读取用户的int类型输入
24 入口参数:无
25 返回值: 用户输入的整数
26 */
27 int getInt(void)
28 {
29 inputType = INT;
30 return atoi(getInput());
31 }
32
33 /**
34 函数功能:读取用户的float类型输入
35 入口参数:无
36 返回值: 用户输入的浮点数
37 */
38 float getFloat(void)
39 {
40 inputType = FLOAT;
41 return (float) atof(getInput());
42 }
43
44 /**
45 函数功能:读取用户输入的字符串,限制必须是整数或浮点数
46 入口参数:无
47 返回值: 数据缓冲区首地址
48 */
49 char* getInput(void)
50 {
51 char c = '\0';
52 pos = 0;
53 c = getch();
54 while (c != '\r') // 回车输入结束
55 {
56 if (c == '\b') // 如果是退格符
57 {
58 if (pos > 0)
59 {
60 pos--;
61 printf("\b \b"); // 删除前一个字符
62 // 先让光标后退一个字符 \b
63 // 然后打印一个空格,消去原先的字符
64 // 然后再让光标后退一个字符
65 }
66 else
67 putchar('\a'); // 响铃,提醒没有字符可删除
68
69 }
70 else if ( pos < (BUFFER_SIZE-1) ) // 防止越界并为'\0'预留空间
71 {
72 if (isValidChar(c)) // 如果是合法字符保存并回显
73 {
74 buffer[pos++] = c; // 保存
75 putchar(c); // 回显
76 }
77 else
78 putchar('\a'); // 响铃,提醒输入非法字符
79 }
80 else // 达到buffer上界
81 {
82 putchar('\a');
83 }
84 c = getch();
85 }// end while (输入回车)
86
87 buffer[pos] = '\0';
88 putchar('\n'); // 将回车字符输出
89
90 if (pos >0)
91 getNumError = 0;
92 else
93 getNumError = 1;
94 return buffer;
95 }
96
97 /**
98 函数功能:判断当前输入的字符是否合法
99 入口参数:无
100 返回值: 非0表示合法,0表示非法
101 */
102 static int isValidChar(char ch)
103 {
104 int result; // 判断结果
105
106 if (ch >= '0' && ch <= '9') // 数字全部接收
107 result = 1;
108 else if (pos == 0 && (ch == '-' || ch == '+'))
109 result = 1; // 第一个字符可以是正负号
110 else if (ch == '.' && inputType == FLOAT && !hasDot())
111 result = 1; // 只有浮点数能输入一次小数点
112 else
113 result = 0;
114
115 return result;
116 }
117
118 /**
119 函数功能:判断是否已经输入了小数点
120 入口参数:无
121 返回值: 非0表示已经输入,0表示未输入
122 */
123 static int hasDot(void)
124 {
125 int i;
126
127 for (i=0; i < pos && buffer[i]!='.'; i++)
128 ;
129
130 return (i < pos);
131 }
132
2 #include <stdlib.h>
3 #include <conio.h>
4 #include <stdio.h>
5
6 #define BUFFER_SIZE 32 // 输入缓冲区大小
7 #define INT 1 // 输入类型,整数
8 #define FLOAT 2 // 输入类型,浮点数
9
10 ////// 全局变量 //////
11 int getNumError = 0;
12 ////// 模块全局变量 //////
13 static int inputType; // 输入类型
14 static char buffer[BUFFER_SIZE]; // 输入缓冲区
15 static int pos = 0; // buffer中有效数据的末尾位置 + 1
16
17 ///// 模块内部函数,共享输入缓冲区 //////
18 static char* getInput(void);
19 static int isValidChar(char c);
20 static int hasDot(void);
21
22 /**
23 函数功能:读取用户的int类型输入
24 入口参数:无
25 返回值: 用户输入的整数
26 */
27 int getInt(void)
28 {
29 inputType = INT;
30 return atoi(getInput());
31 }
32
33 /**
34 函数功能:读取用户的float类型输入
35 入口参数:无
36 返回值: 用户输入的浮点数
37 */
38 float getFloat(void)
39 {
40 inputType = FLOAT;
41 return (float) atof(getInput());
42 }
43
44 /**
45 函数功能:读取用户输入的字符串,限制必须是整数或浮点数
46 入口参数:无
47 返回值: 数据缓冲区首地址
48 */
49 char* getInput(void)
50 {
51 char c = '\0';
52 pos = 0;
53 c = getch();
54 while (c != '\r') // 回车输入结束
55 {
56 if (c == '\b') // 如果是退格符
57 {
58 if (pos > 0)
59 {
60 pos--;
61 printf("\b \b"); // 删除前一个字符
62 // 先让光标后退一个字符 \b
63 // 然后打印一个空格,消去原先的字符
64 // 然后再让光标后退一个字符
65 }
66 else
67 putchar('\a'); // 响铃,提醒没有字符可删除
68
69 }
70 else if ( pos < (BUFFER_SIZE-1) ) // 防止越界并为'\0'预留空间
71 {
72 if (isValidChar(c)) // 如果是合法字符保存并回显
73 {
74 buffer[pos++] = c; // 保存
75 putchar(c); // 回显
76 }
77 else
78 putchar('\a'); // 响铃,提醒输入非法字符
79 }
80 else // 达到buffer上界
81 {
82 putchar('\a');
83 }
84 c = getch();
85 }// end while (输入回车)
86
87 buffer[pos] = '\0';
88 putchar('\n'); // 将回车字符输出
89
90 if (pos >0)
91 getNumError = 0;
92 else
93 getNumError = 1;
94 return buffer;
95 }
96
97 /**
98 函数功能:判断当前输入的字符是否合法
99 入口参数:无
100 返回值: 非0表示合法,0表示非法
101 */
102 static int isValidChar(char ch)
103 {
104 int result; // 判断结果
105
106 if (ch >= '0' && ch <= '9') // 数字全部接收
107 result = 1;
108 else if (pos == 0 && (ch == '-' || ch == '+'))
109 result = 1; // 第一个字符可以是正负号
110 else if (ch == '.' && inputType == FLOAT && !hasDot())
111 result = 1; // 只有浮点数能输入一次小数点
112 else
113 result = 0;
114
115 return result;
116 }
117
118 /**
119 函数功能:判断是否已经输入了小数点
120 入口参数:无
121 返回值: 非0表示已经输入,0表示未输入
122 */
123 static int hasDot(void)
124 {
125 int i;
126
127 for (i=0; i < pos && buffer[i]!='.'; i++)
128 ;
129
130 return (i < pos);
131 }
132
主程序:main.cpp
代码
1 #include <stdio.h>
2 #include "getNum.h"
3
4 void main()
5 {
6 float f;
7
8 printf("Test getFloat().\n");
9
10 do
11 {
12 printf("Input a number: ");
13 f = getFloat();
14 if (getNumError != 0)
15 printf("You input nothing.\n");
16 else
17 printf("What you input is %f\n", f);
18 } while (f != -1);
19 }
2 #include "getNum.h"
3
4 void main()
5 {
6 float f;
7
8 printf("Test getFloat().\n");
9
10 do
11 {
12 printf("Input a number: ");
13 f = getFloat();
14 if (getNumError != 0)
15 printf("You input nothing.\n");
16 else
17 printf("What you input is %f\n", f);
18 } while (f != -1);
19 }