[C语言][K&R][book] 实现 getfloat 函数

By | October 30, 2019

这是 K&R 的《C程序设计语言第2版》第 5 章练习 5-2 我写的答案,但不一定是标准答案。经过一系列测试,没有发现 Bug。如果您发现 Bug,可能选择告诉我。欢迎交流!记得 联系我 哦~~

题目要求:
练习 5-2 模仿 getint 的实现方法,编写一个读取浮点数的函数 getfloatgetfloat 函数的返回值应该是什么类型?

我觉得函数返回值应该是 int 类型,这与函数参数无关。

测试用例:

-ac123    +56.12a    99ncd .123     bcd344.12    abcd   bac+12.3 ook-92  von+   -.03    -123.574    +0.453    8.000     0.000     +abc512.12     88    12.88aaa123     588.0

以下是我的答案:

/*================================================================
*   Copyright (C) 2019 Navin Xu. All rights reserved.
*   
*   Filename    :p083-5.2-ex5-2.c
*   Author      :Navin Xu
*   E-Mail      :admin@navinxu.com
*   Create Date :2019年10月30日
*   Description :
================================================================*/
#include <stdio.h>
#include <ctype.h>

#define BUFFERMAX 100
// 此值是关键
// 关系到保存输入的数组的大小
// 测试时是 18,
// 因为提供 18 个用于测试的值
// 正式应用时可以按需调整
#define MAXLEN 18

int bufferIndex = 0;
int buffer[BUFFERMAX];

int getch();
void ungetch(int);
int getfloat(double *p);

int main() {

    double array[MAXLEN] = {0.0};
    for (int i = 0; i < MAXLEN && getfloat(&array[i]) != EOF; ++ i) 
        printf("%.2f,", array[i]);


    return 0;
}

/**
 *
 *
 * 获取一个字符
 * 从标准输入,或者从缓存
 * 当缓存中有字符时,就从缓存中取
 */
int getch() {
    return (bufferIndex > 0) ? buffer[--bufferIndex] : getchar();
}

/**
 *
 *
 * 保存一个字符到缓存中
 * 本函数的主要作用是当在程序中获得多余的字符时,
 * 该字符在下一次的字符读取时可能有用,可能无用,
 * 可以先把它放进缓存,等待下次读取。
 */
void ungetch(int c) {
    if (bufferIndex < BUFFERMAX)
        buffer[bufferIndex ++] = c;
}

int getfloat(double *p) {
    int c, sign;
    sign = 1;
    *p = 0.0;

    while (isspace(c = getch()))
        ;

    if (!isdigit(c) && c != EOF && c != '+' && c != '-' && c != '.') {
        c = getch();
        while (!isspace(c) && c != EOF) {
            c = getch();
        }
    }

    if (c == '+' || c == '-') {
        sign = (c == '-') ? -1 : 1;
        c = getch();
    }

    if (!isdigit(c) && c != '.') {
        while (!isspace(c) && c != EOF) {
            c = getch();
        }
    }

    while (isdigit(c)) {
        *p = 10 * *p + c -'0';
        c = getch();
    }

    // 获取小数部分
    if (c == '.') {
        int ten = 1;
        double result = 0;
        while (isdigit(c = getch())) {
            result = 10 * result + c - '0';
            ten *= 10;
        }

        result /= ten;
        *p += result;
    }
    if (*p != 0.00)
        *p *= sign;

    while (!isspace(c) && !isdigit(c) && c != EOF) {
        c = getch();
    } 

    if (isdigit(c)) {
        c = getch();
        while (!isspace(c) && c != EOF) {
            c = getch();
        }
    }

    if (c != EOF)
        ungetch(c);

    return c;
}

鉴于本人的相关知识储备以及能力有限,本博客的观点和描述如有错漏或是有考虑不周到的地方还请多多包涵,也欢迎指正,一起学习,共同进步。如果本文对您有帮助,而且让您觉得值得为内容付费,那么就请赞助(打赏)一下本人,这不强制。打赏支持微信支付,方法是使劲地戳一下下方的“打赏”按钮,然后得到微信收款的二维码,再用微信支付扫一下,就像买菜那样。祝好!