前言:在上篇文章中柬泽,這個C++程序的day1版本,實(shí)現(xiàn)讀取配置文件嫁蛇,然后執(zhí)行cd和ls命令锨并,把獲得版本號目錄,分成要保留的和要刪除的睬棚。這篇文章中第煮,把執(zhí)行命令行和讀取配置文件抽離成兩個單獨(dú)的函數(shù),并添加mv命令闸拿,把要刪除的目錄移動到垃圾桶目錄空盼。
一书幕、改動后的main函數(shù)(removeOldDotnet.cpp)
//
// Created by Leiah on 2023/5/18.
//
#include <iostream>
#include <fstream>
#include <cstring>
#include "CompareVersion.h"
#include "DivideGroup.h"
#include "GetDifference.h"
#include "ExecuteCommand.h"
#include "GetConfig.h"
string CD_CMD = "cd && ls";
string MV_CMD = "mv";
using namespace std;
const char * filename = "dotnet_Install_Directory.txt";
int pathLimit = 0;
int main() {
array<string,4> dotnetDirPath{};
string dotnetPath;
string dirToRemove[20];
array<string, 20> path{};
int count{0};
const char * c_str;
// 打開文件
dotnetDirPath = getConfiguration(filename);
char ps[1024] {0}, ch[1024];
// 拼接命令行的命令和參數(shù)新荤,目前只處理了Microsoft.NETCore.App文件夾
c_str = (CD_CMD.insert(3,dotnetDirPath[2])).c_str();
strcpy(ps, c_str);
executeCommand(ps, path);
cout << "Here are all the dotnet-runtimes: ";
for(const string& str: path) {
if(!str.empty()) {
dirToRemove[count++] = str;
cout << str << " ";
}
}
cout << endl;
/* 判斷dirToRemove中具體是哪些文件夾要移除
* 比如:6.0.10 6.0.11 6.0.12 7.0.12 7.0.13 8.0.14
* 只保留 6.0.12 7.0.13 8.0.14
*/
struct dirGroup dg = DivideGroup::divideGroup(dirToRemove);
cout << "Here are the dotnet dir to reserve: ";
int i;
for(i = 0; i < dg.num; i++)
cout << dg.dir[i] << ' ';
cout << endl;
string temp = GetDifference::getDiff(dirToRemove,count+1,dg.dir,dg.num);
cout << "Here are the directory to remove: " << temp << endl;
// mv命令拼接目錄,把要刪除的目錄移動到垃圾桶目錄
c_str = MV_CMD.append(temp).append(" ").append(dotnetDirPath[3]).c_str();
cout << c_str << endl;
// strcpy(ps, c_str);
// executeCommand(ps, path);
cout << "Done!\n" << endl;
return 0;
}
二台汇、讀取配置文件的函數(shù)(GetConfig.h)
//
// Created by Leiah on 2023/5/18.
//
#include <iostream>
#include <fstream>
using namespace std;
/*
* 打開配置文件filename
* 獲取4條路徑:dotnet-sdks苛骨、Microsoft.AspNetCore.App、Microsoft.NETCore.App苟呐、TrashPath
* */
array<string,4> getConfiguration(const string filename) {
int pathLimit = 0;
string dotnetPath;
array<string,4> dotnetDirPath;
// 打開文件
ifstream fin(filename);
if (!fin.is_open()) {
cout << "Open " << filename << " failed." << endl;
} else {
// 獲得文件中的路徑
while(pathLimit < 4 && getline(fin, dotnetPath)) {
dotnetDirPath[pathLimit++] = dotnetPath.substr(dotnetPath.find(':') + 1);
}
}
fin.close();
return dotnetDirPath;
}
三痒芝、執(zhí)行命令行的函數(shù)(ExecuteCommand.h)
//
// Created by Leiah on 2023/5/18.
//
#include <iostream>
using namespace std;
/*
* cmd: 要執(zhí)行的命令行命令
* path:獲取命令行執(zhí)行后的輸出,并返回
* */
void executeCommand(char * cmd, array<string ,20> & path) {
FILE * pcmd = popen(cmd, "r");
char ch[1024];
int count = 0;
if (!pcmd) {
cout << "popen " << *cmd << " failed.\n";
} else {
// 對引用變量inout 取地址牵素,轉(zhuǎn)換為char *
while(fgets(ch,1024,pcmd)){
path[count] = ch;
path[count].erase(path[count].find('\n'));
count++;
}
}
pclose(pcmd);
}
四严衬、運(yùn)行結(jié)果
C++打印dotnet運(yùn)行時——day2版本.jpeg
五、總結(jié)
day1版本的程序笆呆,使用了一個新的C++容器array请琳,即array<string, 4> path
的變量,這樣可以把4個字符串目錄存儲進(jìn)去用作函數(shù)參數(shù)赠幕,這樣在調(diào)用函數(shù)的時候使用引用變量俄精,就可以直接修改傳參而不用返回任何值。