go语言中的Scanf()输入函数

news2025/4/9 6:18:53

Scanf() 第一种情况

package main

import "fmt"

func main() {
    var a int
    for {
       fmt.Println("请输入一个整数:")
       fmt.Scanf("%d", &a)
       fmt.Println("----------------", a)
    }
}

运行结果:

在这里插入图片描述

解释:

出现这种现象是因为程序执行的逻辑顺序所致。具体过程如下:
1.第一次循环输入 :

  • 当输入 1 并按下 Enter 键时,实际输入的数据是 1\n。
  • fmt.Scanf(“%d”, &a) 会读取 1 这个整数,赋值给变量 a。此时,换行符 \n 还留在输入缓冲区中。
  • 然后程序执行 fmt.Println(a),输出 1 到控制台。

2.进入下一次循环:

  • 控制台打印 “请输入一个整数:”,这是 fmt.Print(“请输入一个整数:”) 的输出。
  • 此时,缓冲区中仍然有上一次输入残留的 \n。当 fmt.Scanf(“%d”, &a) 尝试读取时,发现缓冲区中的字符 \n 不是整数格式,导致读取失败。
  • 由于 Scanf 的读取失败,并没有为 a 赋新值,a 保持了之前的值 1。但是读取失败之后,程序继续循环,再次打印 “请输入一个整数:”,使控制台显示了两次 “请输入一个整数:”。

3.第二次输入:

  • 由于上一次的换行符造成了读取失败,程序这一次没有等待新的输入,就直接进入下一次循环,提示 “请输入一个整数:”。

解决方法

可以在读取失败后手动清除缓冲区中的换行符,避免这种情况。之前提到的使用 bufio.Reader 来清空输入缓冲区的方式可以解决这个问题。
修改后的代码如下:

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    var a int
    reader := bufio.NewReader(os.Stdin) // 创建一个 bufio.Reader
    for {
        fmt.Print("请输入一个整数:")
        _, err := fmt.Scanf("%d", &a)
        if err != nil {
            fmt.Println("输入无效,请输入一个整数")
            // 清除缓冲区中的剩余内容
            reader.ReadString('\n')
            continue
        }
        fmt.Println(a)
        // 清除缓冲区中的换行符,防止干扰下次输入
        reader.ReadString('\n')
    }
}

这样处理后,可以确保每次输入都能正确读取,避免因换行符残留导致的错误。

Scanf() 第二种情况

package main

import "fmt"

func main() {
    var a int
    var b string
    fmt.Println("请输入一个整数和一个字符串(如:123 hello):")
    fmt.Scanf("%d %s", &a, &b) // 如果输入 "123\nhello",换行符会被忽略
    fmt.Println("----------------", a, b)
}

运行结果:

解释:

出现这个问题的原因是,在执行 fmt.Scanf(“%d %s”, &a, &b) 时,输入了 123 并按下 Enter 键,程序只读取到了一个整数,而未能读取第二个字符串。这是因为 fmt.Scanf 解析输入时遇到了换行符,而 %s 格式要求必须在同一行读取字符串。

具体原因

当你输入 123 并按下 Enter 键时,Scanf 会按照格式化字符串 %d %s 的顺序尝试读取数据:

1.%d 读取到整数 123,这一步成功。
2.紧接着,Scanf 尝试读取一个字符串(由 %s 表示),但遇到了换行符(Enter 键输入的 \n),导致读取字符串失败。
3.因为未能读取到符合 %s 格式的字符串,程序结束了输入处理,只输出了整数的值。

解决方法

可以采用以下几种方式解决这个问题:

方法 1:使用 fmt.Scanln

fmt.Scanln 可以处理换行符,并在读取到换行符时结束输入。修改代码如下:

var a int
var b string
fmt.Print("请输入一个整数和一个字符串(如:123 hello):")
fmt.Scanln(&a, &b) // 使用 Scanln 来读取整数和字符串
fmt.Println("整数:", a)
fmt.Println("字符串:", b)

这种方式下,输入 123 然后按 Enter 键,程序会等待输入第二个字符串。

方法 2:使用 bufio.Reader 读取整行输入

可以使用 bufio.Reader 读取整行输入,然后使用 fmt.Sscanf 来解析输入的数据:

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

func main() {
    var a int
    var b string
    fmt.Print("请输入一个整数和一个字符串(如:123 hello):")
    
    reader := bufio.NewReader(os.Stdin)
    input, _ := reader.ReadString('\n')
    input = strings.TrimSpace(input) // 去除输入的换行符和空白

    fmt.Sscanf(input, "%d %s", &a, &b)
    fmt.Println("整数:", a)
    fmt.Println("字符串:", b)
}

在这个版本中,bufio.NewReader 读取整行输入,然后通过 fmt.Sscanf 解析输入数据。

总结

  • fmt.Scanf 在读取数据时,换行符会导致输入解析中断,从而无法继续读取剩余的数据。
  • fmt.Scanln 和 bufio.Reader 可以更好地处理换行符,以读取用户的完整输入。

Scanf() 键盘录入时,要注意的问题

一定要严格按照格式化字符串的格式输入,比如

1.fmt.Scanf(“%d %s”, &a, &b),%d %s,两者之间是用空格分隔的

正确示例:

在这里插入图片描述

失败示例:

在这里插入图片描述

之所以没有将123hello作为一个整体读取,是因为程序在读取完123后,在读取h时,发现h不符合%d的格式,所以只读取了123,而没有读取hello

2.fmt.Scanf(“%d,%s”, &a, &b),%d,%s,两者之间是用逗号分隔的

正确示例:

在这里插入图片描述

3.fmt.Scanf(“%d%s”, &a, &b),%d%s,两者之间是紧挨着的

正确示例:

在这里插入图片描述

当要输入两个字符串时,应注意的问题:

package main

import "fmt"

func main() {
    var a string
    var b string
    fmt.Println("请输入两个字符串(如:123 hello):")
    fmt.Scanf("%s%s", &a, &b)
    fmt.Println("----------------", a)
    fmt.Println("++++++++++++++++", b)
}

1.当fmt.Scanf(“%s%s”, &a, &b)中的%s%s之间没有任何间隔时,有如下两种情况:

在这里插入图片描述
在这里插入图片描述

2.当fmt.Scanf(“%s %s”, &a, &b)中的%s %s之间用空格间隔时 :

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2225343.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker下载途径

Docker不是Linux自带的,需要我们自己安装 官网:https://www.docker.com/ 安装步骤:https://docs.docker.com/engine/install/centos/ Docker Hub官网(镜像仓库):https://hub.docker.com/ 在线安装docker 先卸载旧的docker s…

C/C++小宇宙代码

系列目录 序号直达链接1C/C爱心代码2C/C跳动的爱心3C/C李峋同款跳动的爱心代码4C/C满屏飘字表白代码5C/C大雪纷飞代码6C/C烟花代码7C/C黑客帝国同款字母雨8C/C樱花树代码9C/C奥特曼代码10C/C圣诞树代码11C/C俄罗斯方块12C/C贪吃蛇13C/C小宇宙代码 目录 系列目录 写在前面 …

LVGL显示图片2——显示GIF图片,图片尺寸注意,图片太大无法显示

1进入图像转换网页中 https://lvgl.io/tools/imageconverter 2选择图片 3设置生成的格式 4点击生成 5复制文件,配置环境 6编写代码() //显示一张动图 void demo_gif(){lv_obj_t* screenlv_scr_act();//声名对象LV_IMG_DECLARE(GIF_1);//创…

【数据集】NCEP辐射数据-用于计算漫射天窗比(diffuse skylight ration)

【数据集】NCEP辐射数据-用于计算漫射天窗比(diffuse skylight ration) 漫射天窗比(diffuse skylight ration)地表反射率计算漫射天窗比计算NCEP辐射数据数据下载参考漫射天窗比(diffuse skylight ration) 基于NCEP辐射数据利用Python代码计算漫射天窗比(diffuse skyli…

【实用知识】Spring Boot 优雅捕捉异常的几种姿势

👉博主介绍: 博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,WEB架构师,阿里云专家博主,华为云云享专家,51CTO 专家博主 ⛪️ 个人社区&#x…

ATom:加州理工学院化学电离质谱仪(CIT-CIMS)的现场数据,V2版

目录 简介 摘要 代码 引用 网址推荐 知识星球 机器学习 ATom: In Situ Data from Caltech Chemical Ionization Mass Spectrometer (CIT-CIMS), V2 ATom:加州理工学院化学电离质谱仪(CIT-CIMS)的现场数据,V2版 简介 该数…

Centos7.9安装MySQL(二进制)

安装包 https://downloads.mysql.com/archives/community/ mysql-8.0.39-linux-glibc2.17-x86_64.tar.xz 1.卸载MariaDB 查看 rpm -qa|grep mariadb卸载 可能名称不一样,记得替换 rpm -e --nodeps mariadb-libs-5.5.68-1.el7.x86_64rpm -qa|grep mariadb 执行…

leetcode228:汇总取件

步骤1:定义题目的计算问题性质 题目要求从一个无重复元素且有序的整数数组 nums 中,找出所有恰好覆盖数组中所有数字的最小区间范围列表。这意味着每个数字都必须被某个区间包含,且没有多余的数字在区间内。 输入:一个有序整数数…

Github 2024-10-28 开源项目周报 Top15

根据Github Trendings的统计,本周(2024-10-28统计)共有15个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目6JavaScript项目4TypeScript项目4Jupyter Notebook项目2C++项目1C#项目1Svelte: 一种新的Web应用程序构建方法 创建周期:2899 天开发…

软件分享丨ImTip输入状态

ImTip软件介绍 ImTip是一款实用的输入法状态跟踪提示工具,官网为https://imtip.aardio.com。 它具有诸多优势,体积小巧仅696KB且免费开源,是单文件绿色软件,无外部依赖,能在多种流行桌面操作系统上流畅运行。其核心…

软硬件开发面试问题大汇总篇——针对非常规八股问题的提问与应答(代码规范与生态管理)

软硬件开发,对于编码规范、生态管理等等综合问题的考察尤为重要。 阐述下环形缓冲区的用途 环形缓冲区(Ring Buffer)是一种固定大小的数据结构,常用于实现数据的流式传输或临时存储。在环形缓冲区中,当到达缓冲区的末尾…

react18中的合成事件与浏览器中的原生事件

React 通过将事件 normalize 以让他们在不同浏览器中拥有一致的属性。 合成事件 SyntheticEvent 实例将被传递给你的事件处理函数,它是浏览器的原生事件的跨浏览器包装器。除兼容所有浏览器外,它还拥有和浏览器原生事件相同的接口,包括 stopP…

Atlas800昇腾服务器(型号:3000)—SwinTransformer等NPU推理【图像分类】(九)

服务器配置如下: CPU/NPU:鲲鹏 CPU(ARM64)A300I pro推理卡 系统:Kylin V10 SP1【下载链接】【安装链接】 驱动与固件版本版本: Ascend-hdk-310p-npu-driver_23.0.1_linux-aarch64.run【下载链接】 Ascend-…

华为配置 之 STP

目录 简介: STP: RSTP: 如何改变根网桥: (1)改变优先级: (2)改变root: 各端口的状态: 总结: 简介: STP(Spanning Tree Protoco…

【数据分析】Power BI的使用教程

目录 1 Power BI架构1.1 Power BI Desktop1.2 Power BI服务1.3 Power BI移动版 2 Power Query2.1 Power Query编辑器2.2 Power Query的优点2.3 获取数据2.4 数据清洗的常用操作2.4.1 提升标题2.4.2 更改数据类型2.4.3 删除错误/空值2.4.4 删除重复项2.4.5 填充2.4.6 合并列2.4.…

JAVA面试八股文(五)

#1024程序员节|征文# 在1024程序员节这个特别的日子里,首先,我想对每一位程序员表示最诚挚的祝贺!祝愿大家在未来的日子里,能够继续热爱编程、追求卓越,携手共创更美好的科技未来!让我们共同庆祝…

基于Django+python的酒店客房入侵检测系统设计与实现

项目运行 需要先安装Python的相关依赖:pymysql,Django3.2.8,pillow 使用pip install 安装 第一步:创建数据库 第二步:执行SQL语句,.sql文件,运行该文件中的SQL语句 第三步:修改源…

Luma API 的使用

Luma 是一个专注于高质量视频生成的平台,用户只需上传素材,即可根据不同的风格和效果自动生成高质量的视频。该 AI 视频生成器是由来自知名科技公司的团队开发,旨在让每个人在不使用复杂编辑工具的情况下,轻松制作优秀的视频。 然…

docker sameersbn/bind dns服务器

1. 安装 #下载docker 镜像 docker pull sameersbn/bind#运行 53端口若被占用会启动失败 docker run --name dns -d --restartalways \ --publish 53:53/tcp \ --publish 53:53/udp \ --publish 10000:10000/tcp \ -v /etc/localtime:/etc/localtime \ -v /data/bind/:/data \…

Semantic Kernel进阶:创建和管理聊天(ChatCompletion)历史记录对象(四)

一、引言 在构建基于Semantic Kernel的AI应用时,聊天历史记录对象(Chat History)是维护对话上下文和连续性的关键。本文将一步步指导你如何创建和管理聊天历史记录对象,从而为你的AI代理提供一个强大的对话管理工具。 二、聊天…