Cpp实现window上cmd执行效果

Cpp实现window上cmd执行效果

文章目录

  • Cpp实现window上cmd执行效果
      • 1.头文件包含部分
      • 2.`main` 函数部分
      • 3. 获取当前工作目录部分
      • 4.主循环部分
      • 5.退出条件部分
      • 6.处理 `cd` 命令部分
      • 7.执行其他命令部分
      • 8.读取命令输出部分
      • 9.关闭管道并处理返回码部分
      • 10.源码

1.头文件包含部分

#include <iostream>
#include <string>
#include <cstdlib>
#include <windows.h>  // 用于 Windows 系统的 SetCurrentDirectory 函数
  • #include <iostream>:引入标准输入输出流库,这样就能使用 std::cout 进行输出,std::cin 进行输入。
  • #include <string>:引入标准字符串库,用于处理 std::string 类型的字符串。
  • #include <cstdlib>:引入标准库,包含了一些常用的函数和类型,这里可能在后续使用 _popen 等函数时会依赖它。
  • #include <windows.h>:引入 Windows 系统的头文件,包含了许多 Windows API 函数,这里主要使用 GetCurrentDirectoryASetCurrentDirectoryA 函数。

2.main 函数部分

int main() {std::string inputCommand;char currentDir[MAX_PATH];
  • int main():程序的入口函数,返回值为 int 类型,通常返回 0 表示程序正常结束。
  • std::string inputCommand;:定义一个 std::string 类型的变量 inputCommand,用于存储用户输入的命令。
  • char currentDir[MAX_PATH];:定义一个字符数组 currentDir,用于存储当前工作目录,MAX_PATH 是 Windows 系统中定义的最大路径长度。

3. 获取当前工作目录部分

// 使用 ANSI 版本的函数
if (!GetCurrentDirectoryA(MAX_PATH, currentDir)) {std::cerr << "无法获取当前工作目录,错误代码: " << GetLastError() << std::endl;return 1;
}
  • GetCurrentDirectoryA(MAX_PATH, currentDir):调用 Windows API 函数 GetCurrentDirectoryA 获取当前工作目录,并将其存储到 currentDir 数组中。A 表示使用 ANSI 版本,以处理 char* 类型的字符串。
  • if (!GetCurrentDirectoryA(MAX_PATH, currentDir)):如果获取当前工作目录失败,GetCurrentDirectoryA 函数返回 0,则执行 if 语句块。
  • std::cerr << "无法获取当前工作目录,错误代码: " << GetLastError() << std::endl;:使用 std::cerr 输出错误信息,GetLastError() 函数返回最后一次系统调用的错误代码。
  • return 1;:返回非零值表示程序异常结束。

4.主循环部分

while (true) {std::cout << currentDir << "> ";  // 显示当前工作目录作为提示符std::getline(std::cin, inputCommand);
  • while (true):创建一个无限循环,使程序持续等待用户输入命令。
  • std::cout << currentDir << "> ";:输出当前工作目录和一个大于号作为提示符,模拟命令行界面。
  • std::getline(std::cin, inputCommand);:从标准输入读取一行内容,并将其存储到 inputCommand 变量中。

5.退出条件部分

if (inputCommand == "exit") {break;
}
  • if (inputCommand == "exit"):检查用户输入的命令是否为 exit
  • break;:如果是 exit,则跳出循环,结束程序。

6.处理 cd 命令部分

// 处理 cd 命令
if (inputCommand.substr(0, 2) == "cd") {std::string newDir = inputCommand.substr(3);// 使用 ANSI 版本的函数if (SetCurrentDirectoryA(newDir.c_str())) {// 更新当前工作目录if (!GetCurrentDirectoryA(MAX_PATH, currentDir)) {std::cerr << "无法更新当前工作目录,错误代码: " << GetLastError() << std::endl;continue;}}else {std::cerr << "无法更改目录到 " << newDir << std::endl;}continue;
}
  • if (inputCommand.substr(0, 2) == "cd"):检查用户输入的命令是否以 cd 开头。
  • std::string newDir = inputCommand.substr(3);:如果是以 cd 开头,提取 cd 后面的目录路径,存储到 newDir 变量中。
  • SetCurrentDirectoryA(newDir.c_str()):调用 Windows API 函数 SetCurrentDirectoryA 尝试将当前工作目录更改为 newDir
  • if (!GetCurrentDirectoryA(MAX_PATH, currentDir)):如果更改成功,再次调用 GetCurrentDirectoryA 函数更新 currentDir 数组。如果更新失败,输出错误信息并继续下一次循环。
  • else:如果更改目录失败,输出错误信息并继续下一次循环。
  • continue;:跳过本次循环的剩余部分,继续等待用户输入下一个命令。

7.执行其他命令部分

// 使用 _popen 打开一个管道来执行命令
FILE* pipe = _popen(inputCommand.c_str(), "r");
if (!pipe) {std::cerr << "无法打开管道!" << std::endl;continue;
}
  • _popen(inputCommand.c_str(), "r"):使用 _popen 函数打开一个管道,执行用户输入的命令,并以只读模式读取命令的输出。
  • if (!pipe):如果打开管道失败,输出错误信息并继续下一次循环。

8.读取命令输出部分

// 用于存储命令输出的缓冲区
char buffer[1024];
std::string res = "";
// 从管道中读取命令输出
while (fgets(buffer, sizeof(buffer), pipe) != nullptr) {res += buffer;
}
  • char buffer[1024];:定义一个字符数组 buffer,用于存储从管道中读取的命令输出。
  • std::string res = "";:定义一个 std::string 类型的变量 res,用于存储命令的完整输出。
  • while (fgets(buffer, sizeof(buffer), pipe) != nullptr):使用 fgets 函数从管道中读取数据,每次最多读取 sizeof(buffer) 个字符,直到读取到文件末尾(返回 nullptr)。读取到的数据存储在 buffer 中,并追加到 res 变量中。

9.关闭管道并处理返回码部分

// 关闭管道
int returnCode = _pclose(pipe);
if (returnCode == 0) {std::cout << "命令执行成功。" << std::endl;std::cout << "命令输出信息如下:" << std::endl;std::cout << res << std::endl;
}
else {std::cout << "命令执行失败,返回码:" << returnCode << std::endl;
}
  • _pclose(pipe):关闭管道并返回命令的退出状态码。
  • if (returnCode == 0):检查返回码是否为 00 通常表示命令执行成功,此时输出成功信息和命令的输出内容;否则输出失败信息和返回码。

10.源码

#include <iostream>
#include <string>
#include <cstdlib>
#include <windows.h>  // 用于 Windows 系统的 SetCurrentDirectory 函数int main() {std::string inputCommand;char currentDir[MAX_PATH];// 使用 ANSI 版本的函数if (!GetCurrentDirectoryA(MAX_PATH, currentDir)) {std::cerr << "无法获取当前工作目录,错误代码: " << GetLastError() << std::endl;return 1;}while (true) {std::cout << currentDir << "> ";  // 显示当前工作目录作为提示符std::getline(std::cin, inputCommand);if (inputCommand == "exit") {break;}// 处理 cd 命令if (inputCommand.substr(0, 2) == "cd") {std::string newDir = inputCommand.substr(3);// 使用 ANSI 版本的函数if (SetCurrentDirectoryA(newDir.c_str())) {// 更新当前工作目录if (!GetCurrentDirectoryA(MAX_PATH, currentDir)) {std::cerr << "无法更新当前工作目录,错误代码: " << GetLastError() << std::endl;continue;}}else {std::cerr << "无法更改目录到 " << newDir << std::endl;}continue;}// 使用 _popen 打开一个管道来执行命令FILE* pipe = _popen(inputCommand.c_str(), "r");if (!pipe) {std::cerr << "无法打开管道!" << std::endl;continue;}// 用于存储命令输出的缓冲区char buffer[1024];std::string res = "";// 从管道中读取命令输出while (fgets(buffer, sizeof(buffer), pipe) != nullptr) {res += buffer;}// 关闭管道int returnCode = _pclose(pipe);if (returnCode == 0) {std::cout << "命令执行成功。" << std::endl;std::cout << "命令输出信息如下:" << std::endl;std::cout << res << std::endl;}else {std::cout << "命令执行失败,返回码:" << returnCode << std::endl;}}return 0;
}

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

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

相关文章

STM32 HAL库FreeRTOS 中断管理

一、引言 在嵌入式系统开发中&#xff0c;STM32 微控制器凭借其高性能、低功耗和丰富的外设资源&#xff0c;被广泛应用于各种领域。FreeRTOS 作为一款轻量级、开源且功能强大的实时操作系统&#xff0c;为多任务处理提供了良好的支持。中断是嵌入式系统中实现实时响应外部事件…

在 UE5 编辑器中,由于游戏设置 -> EV100 设置,点击播放前后的光照不同。如何保持点击播放前后的光照一致?

​In Unreal Engine 5 (UE5), discrepancies in lighting between the editor and play modes are often due to auto exposure settings, particularly when using the EV100 system. To maintain consistent lighting across both modes, follow these steps:​YouTube1Epic …

[python] set

1.添加元素 在 Python 中&#xff0c;向 set 添加一个元素可以使用 add() 方法。如果添加的元素已经存在于 set 中&#xff0c;add() 不会重复添加&#xff08;因为 set 具有自动去重的特性&#xff09;。 方法 1&#xff1a;add(element)&#xff08;添加单个元素&#xff0…

第一期第18讲26:23

shell脚本以 .sh为后缀&#xff0c;里面存放着一行行要运行的linux指令。 shell脚本第一行一定为 #!/bin/bash&#xff0c;表示使用bash。 shell文件举例如下&#xff1a; #!/bin/bash echo "hello shell!" shell文件默认没有可执行权限&#xff0c;因此 chmod 777 m…

解决 Ubuntu 下 VTune 无法收集 CPU 硬件时间计数数据的问题

解决 Ubuntu 下 VTune 无法收集 CPU 硬件时间计数数据的问题 在 Ubuntu 上使用 Intel VTune Profiler 时遇到无法收集 CPU 硬件性能计数器数据的问题&#xff0c;通常是由于权限和系统配置问题导致的。以下是解决方案&#xff1a; 1. 检查并加载性能监控模块 首先确保 Linux…

健康元 以韧性换弹性

拼韧性的时候到了&#xff01; 一面是复杂的市场、政策环境与医药行业转型所叠加形成的向下压力&#xff1b;一面是AI技术深度赋能医药企业创新加速的向上机遇。 中国药企在经历了一轮群体性低潮期后&#xff0c;进入“结构性”分化的阶段。 在这一阶段上&#xff0c;一些财…

csv数据的读取

在地理信息系统&#xff08;GIS&#xff09;项目中&#xff0c;CSV&#xff08;Comma-Separated Values&#xff09;文件是一种常见的数据格式&#xff0c;用于存储表格数据。CSV 文件因其简单易用、可被多种软件读取而广泛应用于数据交换和存储。ArcPy 提供了强大的功能&#…

android Stagefright框架

作为Android音视频开发人员&#xff0c;学习Stagefright框架需要结合理论、源码分析和实践验证。以下是系统化的学习路径&#xff1a; 1. 基础准备 熟悉Android多媒体体系 掌握MediaPlayer、MediaCodec、MediaExtractor等核心API的用法。 理解Android的OpenMAX IL&#xff08…

【基于WSAAsyncSelec模型的通信程序设计】

文章目录 一、实验背景与目的二、实验设计与实现思路1. 设计思想2. 核心代码实现 总结 一、实验背景与目的 这次实验主要是为了让大家了解基于 WSAAsyncSelect 模型通信程序的编写、编译和执行过程。通过实践操作&#xff0c;深入掌握这种模型在实现计算机之间通信时的应用。 …

JAVA:利用 Apache Tika 提取文件内容的技术指南

1、简述 Apache Tika 是一个强大的工具,用于从各种文件中提取内容和元数据。📄Tika 支持解析文档、📸图像、🎵音频、🎥视频文件以及其他多种格式,非常适合构建🔍搜索引擎、📂内容管理系统和📊数据分析工具。 样例代码:https://gitee.com/lhdxhl/springboot-…

数码管静态显示一位字符(STC89C52单片机)

#include <reg52.h> sbit ADDR0 P1^0; sbit ADDR1 P1^1; sbit ADDR2 P1^2; sbit ADDR3 P1^3; sbit ENLED P1^4; //用数组来存储数码管的真值表&#xff0c;数组将在下一章详细介绍 unsigned char code LedChar[] { 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82…

计算机视觉与深度学习 | 工业视觉缺陷检测如何检小缺陷?背景概述,原理,检测难点,常用的检测算法,算法评估指标,新项目算法选择,算法部署

工业视觉小缺陷检测技术解析 背景概述 工业视觉缺陷检测是智能制造中质量控制的核心环节,而小缺陷检测(如微米级划痕、点状污渍、细微裂纹等)因其目标小、易受干扰等特点,成为技术难点。随着制造业对精度要求提升(如3C电子、半导体、精密零部件行业),传统人工目检和基…

OBS 日期时间.毫秒时间脚本 date-and-time.lua

文章目录 OBS 日期时间.毫秒时间脚本&#xff1a;效果 OBS 日期时间.毫秒时间脚本&#xff1a; obs obslua source_name ""last_text "" format_string "" activated false-- 此函数用于获取精确的毫秒级时间戳&#…

进程和线程(1)

前言&#xff1a; 在计算机中cpu就像一座工厂&#xff0c;这个工厂里面有许多的车间&#xff0c;但是假如工厂的电力有限&#xff0c;一次只能供给一个车间使用&#xff0c;也就是说当一个车间在进行工作的时候&#xff0c;其他车间是不能工作的&#xff08;单个cpu只能运行一…

入门-C编程基础部分:16、 预处理器

飞书文档https://x509p6c8to.feishu.cn/wiki/DzSJwsGiTiXkeCkyEYUcuXbKnbf C 预处理是编译过程中一个单独的步骤&#xff0c;是一个文本替换工具而已。所有的预处理命令都是以井号&#xff08;#&#xff09;开头。 指令描述#define定义宏#ifdef如果宏已经定义&#xff0c;则返…

Ubuntu下安装和卸载MySQL

Ubuntu下安装和卸载MySQL 下面的演示系统版本&#xff1a;Ubuntu 24.04 更新系统软件包 在开始安装之前&#xff0c;建议先更新系统的软件包列表&#xff0c;以确保所有依赖项是最新的。 sudo apt update && sudo apt upgrade -y安装MySQL服务器 Ubuntu的官方软件…

【Python爬虫实战篇】--爬取豆瓣电影信息(静态网页)

网站&#xff0c;&#xff1a;豆瓣电影 Top 250 爬取豆瓣前250电影的信息&#xff0c; F12打开网页控制台&#xff0c;查看网页元素&#xff0c; 发现网页数据直接可以查看到&#xff0c;为静态网页数据&#xff0c;较为简单 目录 1.第一步使用urllib库获取网页 2.第二步使…

【Unity知识点详解】Unity中泛型单例的使用,兼容WebGL

今天来讲下Unity中泛型单例的使用&#xff0c;包含普通单例和继承MonoBehaviour的单例。重点是需要两种泛型单例兼容WebGL平台&#xff0c;话不多说直接开始。 泛型单例的设计目标 作为泛型单例&#xff0c;需要实现以下几个目标&#xff1a; 全局唯一&#xff0c;在程序的整个…

Python进程与线程的深度对比

一、核心概念对比 1. 进程&#xff08;Process&#xff09; 操作系统级独立单元&#xff1a;每个进程拥有独立的内存空间&#xff08;堆、栈、代码段&#xff09; 资源隔离性&#xff1a;崩溃不影响其他进程 多核并行&#xff1a;可充分利用多核CPU资源 2. 线程&#xff0…

Django 入门指南:构建强大的 Web 应用程序

什么是 Django&#xff1f; Django 是一个开源的高层次 Python Web 框架&#xff0c;旨在快速开发安全且可维护的网站。它通过简化常见的 Web 开发任务&#xff0c;帮助开发者专注于开发应用的核心功能。Django 实现了“快速开发”和“尽量少的重复”的理念&#xff0c;提供了…