c语言 获取float

99ANYc3cd6
预计阅读时长 17 分钟
位置: 首页 C语言 正文

使用 scanf 函数 (最常见)

scanf 是C标准库中的函数,用于从标准输入(通常是键盘)读取格式化数据。

c语言 获取float
(图片来源网络,侵删)

基本语法

int scanf(const char *format, ...);
  • format: 格式化字符串,用于告诉scanf期望读取什么样的数据,对于float,格式说明符是 %f
  • 可变参数列表,需要传入与format中说明符数量和类型相匹配的变量的地址。

示例代码

#include <stdio.h>
int main() {
    float price;
    float temperature;
    // 提示用户输入
    printf("请输入一个商品的价格: ");
    // 从键盘读取一个浮点数,存入 price 变量的地址中
    // & 是取地址运算符
    scanf("%f", &price);
    printf("你输入的价格是: %.2f\n", price); // %.2f 表示保留两位小数
    printf("请输入当前的温度: ");
    scanf("%f", &temperature);
    printf("你输入的温度是: %.1f\n", temperature); // %.1f 表示保留一位小数
    return 0;
}

编译和运行

假设你将代码保存为 get_float.c

# 编译 (使用 gcc)
gcc get_float.c -o get_float
# 运行
./get_float

运行示例:

请输入一个商品的价格: 99.98
你输入的价格是: 99.98
请输入当前的温度: 36.6
你输入的温度是: 36.6

使用 scanf_s 函数 (更安全)

scanf_s 是微软在Visual C++ (MSVC) 中引入的一个安全版本的scanf,它在标准C中不是必须的,但在Windows平台上开发时强烈推荐使用。

scanf_sscanf 的主要区别在于,对于读取某些类型的数据(如char, wchar_t, string),它需要一个额外的参数来指定缓冲区的大小,以防止缓冲区溢出,对于%f(读取float)和%lf(读取double),行为与scanf完全相同,不需要额外参数。

示例代码 (仅适用于MSVC编译器,如Visual Studio)

#include <stdio.h>
int main() {
    float score;
    printf("请输入你的考试分数: ");
    // 在MSVC下,使用 scanf_s 读取 float 和 scanf 一样
    scanf_s("%f", &score);
    printf("你的分数是: %f\n", score);
    return 0;
}

注意: 如果你使用的是GCC或Clang等非MSVC编译器,scanf_s是不可用的,为了代码的可移植性,scanf通常是更好的选择。


从字符串转换获取 float

你得到的数据可能不是直接从键盘输入的,而是来自一个字符串(从文件中读取的一行,或者网络接收到的数据),这时,你可以使用标准库中的 strtof 函数。

strtof (string to float) 函数非常强大,因为它可以:

  1. 将字符串开头的数字部分转换为float
  2. 能够识别并跳过前导的空白字符。
  3. 能够处理科学计数法(23e4)。
  4. 最重要的是,它能告诉你转换是否成功,以及是否有额外的非数字字符在字符串后面。

函数原型

float strtof(const char *nptr, char **endptr);
  • nptr: 指向要转换的字符串的指针。
  • endptr: 一个 char** 类型的指针。endptr 不是 NULL,函数会将转换停止后的位置(即第一个非数字字符的地址)存储在 *endptr 指向的变量中,这对于检查整个字符串是否都是有效的数字非常有用。
  • 返回值:
    • 成功时,返回转换后的 float 值。
    • 如果转换的值超出了 float 的表示范围,会返回 HUGE_VALF(表示正无穷)或 -HUGE_VALF(表示负无穷),并设置 errnoERANGE
    • 如果无法转换任何数字(例如字符串是 "abc"),则返回 0

示例代码

#include <stdio.h>
#include <stdlib.h> // 必须包含 strtof 的头文件
#include <errno.h>  // 用于检查 errno
int main() {
    const char *str1 = "123.45";
    const char *str2 = "-99.99";
    const char *str3 = "3.14e2"; // 科学计数法,等于 314.0
    const char *str4 = "  123.45abc"; // 前导空格和尾部字符
    const char *str5 = "hello"; // 无效数字
    char *endptr; // 用于 strtof 的 endptr 参数
    float num;
    // 转换 str1
    num = strtof(str1, &endptr);
    printf("'%s' -> %f\n", str1, num);
    // 转换 str2
    num = strtof(str2, &endptr);
    printf("'%s' -> %f\n", str2, num);
    // 转换 str3
    num = strtof(str3, &endptr);
    printf("'%s' -> %f\n", str3, num);
    // 转换 str4,演示 endptr 的作用
    num = strtof(str4, &endptr);
    printf("'%s' -> %f\n", str4, num);
    printf("转换停止在字符: '%c'\n", *endptr); // 会打印 'a'
    // 转换 str5,演示无效输入
    errno = 0; // 在调用 strtof 前重置 errno
    num = strtof(str5, &endptr);
    if (errno == ERANGE) {
        printf("错误:数值超出范围!\n");
    } else if (endptr == str5) {
        // endptr 仍然指向字符串的开头,说明没有数字被转换
        printf("错误:'%s' 不是有效的数字!\n", str5);
    } else {
        printf("'%s' -> %f\n", str5, num);
    }
    return 0;
}

输出:

'123.45' -> 123.450000
'-99.99' -> -99.990000
'3.14e2' -> 314.000000
'  123.45abc' -> 123.450000
转换停止在字符: 'a'
错误:'hello' 不是有效的数字!

其他注意事项

float vs. double

在C语言中,float 是单精度浮点数,而 double 是双精度浮点数。

  • 精度: double 提供的精度大约是 float 的两倍,能表示更多的小数位。
  • 内存占用: float 通常占用4字节,double 通常占用8字节。
  • 性能: 在现代大多数处理器上,floatdouble 的计算速度几乎没有差别,除非有特殊的内存限制或遵循特定的数据格式标准,否则推荐直接使用 double

如果你使用 doublescanf 的格式说明符是 %lf (long float)。

double my_double;
scanf("%lf", &my_double); // 注意是 lf,不是 f

错误处理

scanf 在读取失败时会返回成功读取的项目个数。scanf("%f %d", &f, &i) 如果用户输入了 abc 123,它会返回 0,因为没有任何数据被成功读取,如果输入了 34 abc,它会返回 1,只成功读取了floatint变量i不会被赋值。

利用这个特性,你可以检查输入是否有效:

float number;
if (scanf("%f", &number) != 1) {
    printf("输入无效,请输入一个数字!\n");
    // 清除输入缓冲区中的错误数据,防止无限循环
    while (getchar() != '\n'); 
}
方法 描述 优点 缺点 适用场景
scanf("%f", ...) 从标准输入读取 简单直接,最常用 不安全,无法检测错误输入 交互式程序,简单的命令行工具
scanf_s("%f", ...) MSVC下的安全版本 在MSVC下更安全 可移植性差 Windows平台下的C程序开发
strtof(...) 从字符串转换 功能强大,能处理科学计数法,提供详细的错误信息 scanf稍复杂 解析文件、网络数据、API返回的字符串等

对于初学者和大多数从键盘输入的场景,scanf("%f", &my_float) 是最需要掌握的方法。

-- 展开阅读全文 --
头像
dede织梦帝国CMS如何选择?
« 上一篇 04-05
Ace织梦CMS有何独特优势?
下一篇 » 04-05

相关文章

取消
微信二维码
支付宝二维码

目录[+]