EOF on Windows

本文深入探讨了在使用Go语言进行编程时,如何正确处理标准输入,特别是针对Ctrl-Z的使用与检测,避免常见问题。通过分析C++程序示例,解释了在不同操作系统下Ctrl-Z的作用,并提供了在Windows环境下检测Ctrl-Z的方法。

最近在学习go时,在运行一个简单的读取标准输入的例子时发现,在控制台上(cmd)输入ctrl-z竟然不能结束程序。以前在学习c/c++时,也遇到过有关的问题,也就是当我想要结束输入时,如果在输入ctrl-z之前又输入了某些其他字符,那么此时标准输入不会被关闭,而当一行中仅有一个ctrl-z时,才能结束输入。下面一个简单的c++程序可以验证这个问题:

#include <iostream>
#include <string>
using namespace std;

int main()
{
    string line;
    while (getline(cin, line)) {
        cout << line << endl;
    }
}

如果我们运行时输入

1234^Z5678

此时如果只按一次回车,是看不到输出的,当我们再按一次回车时,才能看到如下输出

1234->

这里->是输出的一个箭头符号代表^Z,但是当我们输入一行仅包含^Z的字符时,程序会正常结束。这里可以看到

  1. 不在行首的^Z无法关闭标准输入,否则我们应该看到1234而不是上面的输出
  2. ^Z也会被当做一个普通字符
  3. ^Z所在行之后的字符(包括换行)都不会显示,也就是库函数会将^Z之后的该行字符全部丢掉

具体造成这种问题的原因,可以参考All About EOF,文中提到了使用ctrl-z作为伪EOF的历史原因,还提到了使用eof检测函数的一些常见错误。

*nix系统的终端默认使用ctrl-d来结束标准输入,但是ctrl-d其实也不是EOF,EOF只是在当标准输入关闭时,读取后返回的一个特殊值。ctrl-d会被终端解释为关闭标准输入的指令。

在windows的console上,我们可以如下检测^Z

package main

import (
    "bufio"
    "golang.org/x/crypto/ssh/terminal"
    "os"
    "runtime"
)

func main() {
    in := bufio.NewReader(os.Stdin)
    for {
        r, n, err := in.ReadRune()
        if runtime.GOOS == "windows" && terminal.IsTerminal(int(os.Stdin.Fd())) && r == '\x1a' {
            // ctrl-z detected
            break
        }
    }
}

这里检测程序运行在控制台上,以防止当重定向输入时,输入中包含^Z的情况。\x1a^ZASCII码。

### 如何在 Windows 虚拟机中安装 Docker #### 安装前准备 为了成功在 Windows 虚拟机上运行 Docker,需确认以下条件已满足: - 确保虚拟化功能已在 BIOS 中启用[^1]。 - 使用支持 Hyper-V 或 WSL 2 的操作系统版本。 #### 方法一:通过官方指南安装 Docker Desktop on Windows 按照 Docker 官方文档中的说明,可以下载并安装适用于 Windows 的 Docker Desktop 版本。以下是具体操作: 1. 下载适合的 Docker Desktop 版本(例如 v4.15.0),地址为:<https://docs.docker.com/docker-for-windows/install/>。 2. 运行安装程序,并遵循向导完成安装过程。 3. 启动 Docker Desktop 并配置必要的设置,如资源分配和代理设置(如果适用)。 此方法适用于原生 Windows 系统而非嵌套虚拟环境下的场景。对于嵌套虚拟化的特殊情况,请参阅 VMware 和 Hyper-V 配置的相关资料。 #### 方法二:基于 Linux 子系统的 Docker CE 安装 当目标是在 Windows 上运行的 Ubuntu 虚拟机中部署 Docker,则可采用如下流程: 1. **更新包管理器缓存** 执行命令刷新本地存储库索引以获取最新软件列表: ```bash sudo apt-get update || sudo yum makecache fast ``` 2. **安装必要依赖项** 如果尚未安装 `curl` 工具或其他基础组件,可通过以下指令补充缺失部分: ```bash sudo apt-get install curl git -y || sudo yum -y install curl git ``` 3. **添加稳定版仓库密钥与源地址** 添加 Docker 官方 GPG 密钥至 APT/YUM 数据库以便验证签名文件的真实性: ```bash curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null ``` 4. **执行实际安装动作** 利用之前定义好的通道来抓取对应平台上的社区版引擎实例: ```bash sudo apt-get update && sudo apt-get install docker-ce docker-ce-cli containerd.io -y || sudo yum -y install docker-ce ``` 针对国内网络状况不佳的情况,推荐替换阿里云镜像服务作为加速手段之一[^2]: ```bash sudo mkdir -p /etc/docker/ cat <<EOF | sudo tee /etc/docker/daemon.json { "registry-mirrors": ["https://<your-id>.mirror.aliyuncs.com"] } EOF ``` 最后重启守护进程使更改生效: ```bash sudo systemctl daemon-reload && sudo systemctl restart docker ``` #### 解决常见问题 遇到诸如 “E: Sub-process /usr/bin/dpkg returned an error code (1)” 类型报错时,通常是因为磁盘空间不足或者权限不够引起。尝试清理旧数据后再重试一次即可缓解该现象[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值