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>    
  
#include <iostream>:引入标准输入输出流库,这样就能使用 std::cout 进行输出,std::cin 进行输入。#include <string>:引入标准字符串库,用于处理 std::string 类型的字符串。#include <cstdlib>:引入标准库,包含了一些常用的函数和类型,这里可能在后续使用 _popen 等函数时会依赖它。#include <windows.h>:引入 Windows 系统的头文件,包含了许多 Windows API 函数,这里主要使用 GetCurrentDirectoryA 和 SetCurrentDirectoryA 函数。  
 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. 获取当前工作目录部分  
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 命令部分  
if  ( inputCommand. substr ( 0 ,  2 )  ==  "cd" )  { std:: string newDir =  inputCommand. substr ( 3 ) ; 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.执行其他命令部分  
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):检查返回码是否为 0,0 通常表示命令执行成功,此时输出成功信息和命令的输出内容;否则输出失败信息和返回码。  
 10.源码  
# include  <iostream>  
# include  <string>  
# include  <cstdlib>  
# include  <windows.h>   int  main ( )  { std:: string inputCommand; char  currentDir[ MAX_PATH] ; 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 ; } if  ( inputCommand. substr ( 0 ,  2 )  ==  "cd" )  { std:: string newDir =  inputCommand. substr ( 3 ) ; if  ( SetCurrentDirectoryA ( newDir. c_str ( ) ) )  { if  ( ! GetCurrentDirectoryA ( MAX_PATH,  currentDir) )  { std:: cerr <<  "无法更新当前工作目录,错误代码: "  <<  GetLastError ( )  <<  std:: endl; continue ; } } else  { std:: cerr <<  "无法更改目录到 "  <<  newDir <<  std:: endl; } continue ; } 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 ; 
}