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 ;
}