Windows控制台函数:控制台输出函数WriteConsoleA()

目录

什么是 WriteConsoleA?

函数签名

参数详解

返回值

一个最简单的例子

跟 ReadConsoleA 对比

再试一个有趣的例子

为什么传地址给 lpNumberOfCharsWritten?

注意事项

什么是 WriteConsoleA?

WriteConsoleA 是一个 Windows API 函数,用来把文字写到控制台屏幕上。就像你在 C++ 用 std::cout 输出东西,但它是直接跟 Windows 的控制台打交道。

把它想象成一个“送信员”:

  • 你给它一堆信(文字)和一个地址(屏幕的钥匙),它就帮你把信送到屏幕上。

  • 它是 ReadConsoleA 的反向操作:ReadConsoleA 是收信,WriteConsoleA 是送信。

函数签名

它的完整定义是:

BOOL WriteConsoleA(HANDLE hConsoleOutput,         // 屏幕的“钥匙”const VOID* lpBuffer,          // 要送的“信”DWORD nNumberOfCharsToWrite,   // 信有多少字符LPDWORD lpNumberOfCharsWritten,// 记录实际送了多少LPVOID lpReserved              // 不用,写 NULL
);

看起来有点像 ReadConsoleA,对吧?我一个个拆开讲。 

参数详解

1. HANDLE hConsoleOutput - 屏幕的“钥匙”

  • 这是什么:你用 GetStdHandle(STD_OUTPUT_HANDLE) 拿到的屏幕句柄。

  • 作用:告诉 WriteConsoleA:“我要往屏幕上送东西。”

  • 怎么用:

HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);
  • 就像你告诉送信员:“用这个钥匙打开屏幕的信箱。”

2. const VOID* lpBuffer - 要送的“信”

  • 这是什么:你要输出的文字,通常是一个 const char* 字符串。

  • 作用:这是送信员要送出去的内容。

  • 怎么用:

const char* message = "Hello";
  • 想象这是你要寄出去的信,内容是“Hello”。VOID* 表示它可以是任何类型,但我们用 char 就够了。

3. DWORD nNumberOfCharsToWrite - 信有多少字符

  • 这是什么:一个数字,告诉函数“信里有多少字符要送”。

  • 作用:让送信员知道要送多长一段文字。

  • 怎么用:

    • 如果 message 是“Hello”,就写 5(或者用 strlen(message))。

    • 比如:

DWORD length = strlen(message); // 5
  • 这就像告诉送信员:“这封信有 5 个字,别漏了。”

4. LPDWORD lpNumberOfCharsWritten - 记录实际送了多少

  • 这是什么:一个变量的地址,函数会把“实际送出去多少字符”写在这里。

  • 作用:告诉你送信员成功送了多少。

  • 怎么用:

DWORD how_many_written; // 定义一个变量

然后传地址: 

&how_many_written
  • 跟 ReadConsoleA 的 lpNumberOfCharsRead 一样,送信员会记下:“我送了 5 个字符。”

 

为什么传地址给 lpNumberOfCharsWritten?

跟 ReadConsoleA 的 lpNumberOfCharsRead 一样:

  • 函数需要修改 how_many_written,告诉你实际写了多少字符。

  • 传地址(&how_many_written)让函数直接改这个变量。

  • 如果不传地址,函数改不了外面的值。

 

5. LPVOID lpReserved - 不用,写 NULL

  • 这是什么:一个预留参数,微软留着以后可能用。

  • 作用:现在没用。

  • 怎么用:

NULL
  • 就像告诉送信员:“没啥特别要求,正常送就行。”

返回值

  • 返回 BOOL(TRUE 或 FALSE):

    • TRUE:送信成功。

    • FALSE:出错了(比如屏幕钥匙坏了)。

一个最简单的例子

我们写个程序,在屏幕上显示“Hello”:

#include <windows.h>
#include <cstring>int main() {// 1. 拿到屏幕钥匙HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);if (screen == INVALID_HANDLE_VALUE) {return 1; // 钥匙坏了,退出}// 2. 准备信和计数器const char* message = "Hello";    // 要送的信DWORD how_many_written;           // 记录送了多少// 3. 发送信(写到屏幕)WriteConsoleA(screen, message, strlen(message), &how_many_written, NULL);return 0;
}

运行过程:

  1. 拿到钥匙:GetStdHandle(STD_OUTPUT_HANDLE) 给你屏幕的钥匙。

  2. 准备信:

    • message 是“Hello”,长度是 5。

    • how_many_written 是计数器。

  3. 送信:

    • WriteConsoleA 把“Hello”送到屏幕上。

    • how_many_written 变成 5,表示送了 5 个字符。

运行结果:屏幕上显示“Hello”。

跟 ReadConsoleA 对比

参数

ReadConsoleA

WriteConsoleA

第一个

键盘钥匙(输入)

屏幕钥匙(输出)

第二个

箱子(收信)

信(送信)

第三个

最多收多少字符

要送多少字符

第四个

记录实际收了多少(地址)

记录实际送了多少(地址)

第五个

控制选项(NULL)

预留(NULL)

  • ReadConsoleA 是从键盘“收”东西到程序里。

  • WriteConsoleA 是从程序“送”东西到屏幕上。

再试一个有趣的例子

我们结合 SetConsoleCursorPosition,在不同位置写文字:

#include <windows.h>
#include <cstring>int main() {HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);if (screen == INVALID_HANDLE_VALUE) {return 1;}DWORD how_many_written;COORD pos;// 在 (5, 2) 写 "Hi"pos.X = 5; pos.Y = 2;SetConsoleCursorPosition(screen, pos);const char* msg1 = "Hi";WriteConsoleA(screen, msg1, strlen(msg1), &how_many_written, NULL);// 在 (10, 5) 写 "There"pos.X = 10; pos.Y = 5;SetConsoleCursorPosition(screen, pos);const char* msg2 = "There";WriteConsoleA(screen, msg2, strlen(msg2), &how_many_written, NULL);return 0;
}

注意事项

  1. 字符数:

    • nNumberOfCharsToWrite 必须匹配 lpBuffer 的长度,不然可能出错。

    • 用 strlen 确保准确。

  2. 换行:

    • 如果想换行,得在字符串里加 \n,比如 "Hello\n"。

  3. 检查返回值:

if (!WriteConsoleA(screen, message, strlen(message), &how_many_written, NULL)) {return 1; // 出错了
}

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

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

相关文章

【贪心算法】将数组和减半的最小操作数

1.题目解析 2208. 将数组和减半的最少操作次数 - 力扣&#xff08;LeetCode&#xff09; 2.讲解算法原理 使用当前数组中最大的数将它减半&#xff0c;&#xff0c;直到数组和减小到一半为止&#xff0c;从而快速达到目的 重点是找到最大数&#xff0c;可以采用大根堆快速达到…

Prompt engineering设计原则

目录 一、清晰具体的prompt1. 使用分隔符2. 结构化的输出&#xff08;JSON&#xff09;3. 要求模型检查是否满足条件4. 提供少量案例 二、给模型时间去思考1.指定完成任务所需的步骤2. 指导模型在下结论之前找出一个自己的解法 一、清晰具体的prompt 一个合理的prompt设计决定…

Vue 过滤器 filter(s) 的使用

即过滤器是用来格式化数据的一个函数。过滤器不会修改原始数据&#xff0c;它的作用是过滤数据&#xff0c;就是对数据进行加工处理并返回处理后的数据&#xff0c;比如做一些数据格式上的修改&#xff0c;状态转换等。 过滤器分为两种 组件内的过滤器(组件内有效) 全局过滤器…

ESP8266UDP透传

1. 配置 WiFi 模式 ATCWMODE3 // softAPstation mode 响应 : OK 2. PC 连⼊入 ESP8266 softAP 就是连接wifi 3.查询ESP8266设备的IP地址 ATCIFSR 响应: CIFSR: APIP, "192.168.4.1" CIFSR: APMAC, "1a: fe: 34: a5:8d: c6" CIFSR: STAIP, "192.…

高效运行 QwQ-32B + 错误修复

文章目录 QwQ-32B 错误修复⚙️ 官方推荐设置&#x1f44d; 推荐的 llama.cpp 设置&#x1f4d6; 教程&#xff1a;运行和修复的 QwQ-32B1、对于 llama.cpp 及使用 llama.cpp 的引擎&#xff1a;2、下载模型 测试3、测试/评估4、尝试不使用我们的修复方案&#xff1a; &#x…

Jump( 2015-2016 ACM-ICPC Northeastern European Regional Contest (NEERC 15). )

Jump( 2015-2016 ACM-ICPC Northeastern European Regional Contest (NEERC 15). ) 题目大意&#xff1a; 在这个交互式问题中&#xff0c;你需要通过查询系统&#xff0c;逐步找出隐藏的位字符串 S。给定一个偶数 n&#xff0c;表示目标位字符串 S 的长度&#xff0c;你需要通…

Leetcode 刷题记录 06 —— 矩阵

本系列为笔者的 Leetcode 刷题记录&#xff0c;顺序为 Hot 100 题官方顺序&#xff0c;根据标签命名&#xff0c;记录笔者总结的做题思路&#xff0c;附部分代码解释和疑问解答。 目录 01 矩阵置零 方法一&#xff1a;标记数组 方法二&#xff1a;两个标记变量 02 螺旋矩阵…

Java【网络原理】(3)网络编程续

目录 1.前言 2.正文 2.1ServerSocket类 2.2Socket类 2.3Tcp回显服务器 2.3.1TcpEchoServer 2.3.2TcpEchoClient 3.小结 1.前言 哈喽大家好&#xff0c;今天继续进行计算机网络的初阶学习&#xff0c;今天学习的是tcp回显服务器的实现&#xff0c;正文开始 2.正文 在…

C++11新特性 8.final关键字、override关键字

一.final 用法&#xff1a; 1.修饰函数 只能修饰虚函数&#xff0c;阻止子类重写这个函数&#xff0c;final关键字写在函数名的后面。 即该虚函数不可以再被重写。 注意&#xff1a;一般不会在基类中使用&#xff0c;不然没有意义&#xff0c;因为只能修饰虚函数。 2.修饰…

Python实现网络通信:Socket模块与TCP/IP协议全解析

Langchain系列文章目录 01-玩转LangChain&#xff1a;从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块&#xff1a;四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain&#xff1a;从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…

click house扩容方案

《ClickHouse扩容方案解析》 当我们谈论数据库的时候&#xff0c;尤其是像ClickHouse这样专为处理大规模数据分析而设计的列式存储数据库时&#xff0c;扩容是一个不可避免的话题。随着数据量的增长和查询复杂度的提升&#xff0c;原有的硬件资源可能不足以支撑高效的查询响应…

【AGI】智谱开源2025:一场AI技术民主化的革命正在到来

智谱开源2025&#xff1a;一场AI技术民主化的革命正在到来 引言&#xff1a;开源&#xff0c;一场技术平权的革命一、CogView4&#xff1a;中文AI生成的里程碑1. 破解汉字生成的“AI魔咒”2. 开源协议与生态赋能 二、AutoGLM&#xff1a;人机交互的范式跃迁1. 自然语言驱动的跨…

java8中young gc的垃圾回收器选型,您了解嘛

在 Java 8 的 Young GC&#xff08;新生代垃圾回收&#xff09;场景中&#xff0c;对于 ToC的场景&#xff0c;即需要尽可能减少垃圾回收停顿时间以满足业务响应要求的场景&#xff0c;以下几种收集器各有特点&#xff0c;通常 Parnew和 G1 young表现较为出色&#xff0c;下面详…

【数学 矩阵快速幂】P7108 移花接木|普及+

本文涉及知识点 数学 移花接木 题目背景 遥远的圣地生长着一棵不为人知的灵树&#xff0c;或有万山之高。 但有一日&#xff0c;藏匿于根系的腐朽力量爆发&#xff0c;灵树已无法支撑往日屹立冲天的高度。 题目描述 灵树最初的形态可以看作一棵高度为 10 10 10 10 {10}…

2025-03-09 学习记录--C/C++-PTA 习题10-7 十进制转换二进制

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、题目描述 ⭐️ 裁判测试程序样例&#xff1a; #include <stdio.h>void dectobin( int n );int main() {int n;scanf(…

前端 | CORS 跨域问题解决

问题&#xff1a;Access to fetch at http://localhost:3000/save from origin http://localhost:5174 has been blocked by CORS policy: Response to preflight request doesnt pass access control check: No Access-Control-Allow-Origin header is present on the request…

fastapi房产销售系统

说明&#xff1a; 我希望用fastapi写几个接口&#xff0c;查询房产交易系统的几条数据&#xff0c;然后在postman里面测试 查询客户所有预约记录&#xff08;含房源信息&#xff09;需要对应销售经理查询客户所有订单&#xff08;含房源信息&#xff09;统计销售经理名下所有房…

导轨式ARM工业控制器:组态软件平台的“神经中枢”

工业自动化领域&#xff0c;组态软件平台扮演着至关重要的角色。它不仅是工业控制系统的“大脑”&#xff0c;更是实现智能化、高效化生产的关键工具。而作为组态软件平台的硬件支撑&#xff0c;导轨式ARM工控机&#xff08;以下简称“工控机”&#xff09;凭借其紧凑的设计、强…

每日一题——矩阵置零问题的原地算法

矩阵置零问题的原地算法 问题描述示例约束条件进阶要求 问题分析难点分析解题思路 代码实现代码说明 测试用例测试用例 1测试用例 2测试用例 3 总结 问题描述 给定一个 m x n 的矩阵&#xff0c;如果矩阵中的某个元素为 0&#xff0c;则需要将其所在的行和列的所有元素都置为 …

Springboot中的@Value注解:用法与潜在问题探索

在Spring Boot开发中&#xff0c;有个非常实用的注解&#xff0c;那就是Value&#xff01;它可以帮助我们轻松地从配置文件中读取属性值。想象一下&#xff0c;在应用程序中管理各种配置&#xff0c;比如数据库连接信息、服务URL或者API密钥等&#xff0c;使用Value是多么方便呀…