从输入流中读取整形和浮点型数据存储在实参所指的内存空间中

     源自《The C Programming Language》P83 pr5-2:

 

    模仿函数getInt 的实现方法,编写一个读取浮点数的函数getFloat,getFloat函数的返回值应该是什么类型呢?

    代码:

    #include <stdio.h> #include <ctype.h> int getInt(int *); int getFloat(double *); #define SIZE 100 #define MAX_FLT 2147483648 //double 8字节,但2^63太大,此处用2^31作为阈值,其实是不太准确的 //#define MAX_FLT 2.1474836e+009 //当arr_flt定义为float型数组时,if(arr_flt[n] == MAX_FLT)会失效, //而定义为double型数组时,则有效(?),如果如上句那样定义MAX_FLT= //2147483648则不会出现失效这个问题 int main() { int i; int n; int arr_int[SIZE]; double arr_flt[SIZE]; int dim; int reNum; //for(n = 0; n < SIZE && ((reNum = getInt(&arr_int[n])) != EOF); ++n) //当getInt返回值是EOF或0或n >= SIZE时,退出循环 // ; for(i = 0; i < SIZE; ++i) arr_int[i] = MAX_FLT; //for(n = 0; n < SIZE && ((reNum = getFloat(&arr_flt[n])) != EOF); ++n) //if(arr_flt[n] == MAX_FLT) //continue; //for循环中continue语句是直接跳到++n处执行,如果不想跳转到此处而是直接 //跳到条件测试部分,应该用while循环(如下代码) n = 0; while(n < SIZE && ((reNum = getInt(&arr_int[n])) != EOF)) { if(arr_int[n] == MAX_FLT) continue; ++n; } dim = n - 1; n = 0; while(dim-- >= 0) printf("%d ", arr_int[n++]); printf("/n"); return 0; } int getch(); void ungetch(int ); /*************************************************************************** **名称:getInt **功能:从输入流中读取若干字符将他们转化成一个int型数据,存储在实参所指的 内存空间中 **参数:pNum:指向一个int数据的指针 **返回:1:如果从输入流中读取的字符不是EOF,'0' ~ '9','+','-'时,返回0; 2:如果从输入流中读取的字符时EOF,则返回EOF(-1); 3:如果从输入流中读取的若干连续字符能转化成一个有意义的数字时, 返回一个正值; ***************************************************************************/ int getInt(int *pNum) { int c; int d; int sign; sign = 1; while(isspace(c = getch())) //用库函数isspace更全面,不会发生遗漏情况 ; if(!isdigit(c) && c != EOF && c != '+' && c != '-') //当不满足这4种情况时,返回0,下面对这4种情况分别处理 { //ungetch(c); //if(!isspace(c)) *pNum = c; //else //ungetch(c); return 0; } sign = (c == '-') ? -1 : 1; if(c == '+' || c == '-') { d = c; if(!isdigit(c = getch())) { if(c != EOF) ungetch(c); //ungetch(d); *pNum = d; return d; } } for(*pNum = 0; isdigit(c); c = getch()) //将若干连续数字字符转化成int型值 *pNum = 10 * *pNum + (c - '0'); //实参是指针的好处在于能改变其所指向的值 *pNum *= sign; if(c != EOF) ungetch(c); return c; } int getFloat(double *pFlt) //从输入流中获取浮点型数据,不符合要求的字符,全部丢弃 { int c; int sign; int pow; pow = 1; while(isspace(c = getch())) ; if(!isdigit(c) && c != EOF && c != '+' && c != '-' && c != '.') return 0; sign = (c == '-') ? -1 : 1; if(c == '+' || c == '-') if(!isdigit(c = getch())) return 0; for(*pFlt = 0; isdigit(c); c = getch()) *pFlt = 10 * *pFlt + (c - '0'); if(c == '.') if(isdigit(c = getch())) { for(; isdigit(c); c = getch()) { *pFlt = 10 * *pFlt + (c - '0'); pow *= 10; } *pFlt /= pow; *pFlt *= sign; } if(c != EOF) ungetch(c); return c; } #define BUFSIZE 100 //自定义的输入缓冲区容量 int buf[BUFSIZE]; //自定义的输入缓冲区 int bufp; //指向输入缓冲区的指针 int getch() //从自定义的输入缓冲区或OS定义的输入缓冲区中读入一个字符 { return (bufp != 0) ? buf[--bufp] : getchar(); } void ungetch(int num) //将一个字符压回到自定义的输入缓冲区中 { if(bufp >= BUFSIZE) printf("error: buffer full!"); else buf[bufp++] = num; } 

    分析:

   

    疑问:关于MAX_FLT定义:当arr_flt定义为float型数组时,if(arr_flt[n] == MAX_FLT)会失效,

             而定义为double型数组时,则有效,如果如上句那样定义MAX_FLT=2147483648则不会出现失效这个问题?

 

    易错:关于continue语句用在while循环和for循环中差异:

             for(n = 0; n < SIZE && ((reNum = getFloat(&arr_flt[n])) != EOF); ++n)

                   if(arr_flt[n] == MAX_FLT)

                       continue;

             for循环中continue语句是直接跳到++n处执行,如果不想跳转到此处而是直接跳到条件测试部分,应该用while循环(如下代码)

              n = 0;
              while(n < SIZE && ((reNum = getFloat(&arr_flt[n])) != EOF))
              {
                  if(arr_flt[n] == MAX_FLT)
                        continue;
                  ++n;
              }

 

     函数分析:getInt:

                    1,  丢弃字符序列头部的空白字符;

                    2,  分四种情况:isdigit(c),c == EOF, c == '+',c == '-'进行处理,

                         当不满足这四种情况时if(!isdigit(c) && c != EOF && c != '+' && c != '-'),说明c是其他字符(不包含空白字符)

                         将c其保存在*pNum中;

                         然后依次按照这四种情况分别进行处理('+', '-'一起处理)。

                    3,  本函数的实参是指向变量的指针,这样可以在函数中改变实参的值,从而达到一个函数返回多个值的目的。

                        

 

 

你可能感兴趣的:(c,测试,OS,存储,buffer,float)