2021年4月20日 星期二

C++ C 如何獲取命令列的響應後返回的字串

[C/C++] 如何獲取命令列的響應後返回的字串

tags: 部落格文章

這邊以檔案目錄為範例,直接獲取檔案目錄中的字串

核心程式

首先最關鍵的函式是這個,這個可以直接獲取響應的命令

#include <io.h>
vector<string> exec(const string& cmd) {
    FILE* pipe = _popen(cmd.c_str(), "r");
    if (!pipe) throw runtime_error("cmd error");
    vector<string> list;
    for (char buffer[256]=""; !feof(pipe);) {
        if (fgets(buffer, sizeof(buffer), pipe) != NULL and buffer[0]!=0) {
            buffer[strlen(buffer)-1] = 0;
            //cout << buffer << endl;
            list.emplace_back(buffer);
        }
    }
    _pclose(pipe), pipe=nullptr;
    return list;
}

使用範例如下

// 獲取當前目錄文件
auto v = exec("dir /b");
for (auto&& i : v) cout << i << endl;

如此一來就對自己打印出當前目錄的文件了
VS2019預設位置是在該cpp文件的目錄,可以找到cpp文件本身



進階使用範例 - getList

再來是比較進階的,把讀取檔案目錄的cmd代碼整合在一起
寫成簡單易用的函式。預設自動封裝成類別可以直接用

#include <iostream>
#include <vector>
#include <io.h>
#include <direct.h>
using namespace std;
//====================================================
class FileList {
public:
    FileList() = delete;
public:
    // 輸入命令並回存到vector陣列
    static vector<string> exec(const string& cmd) {
        FILE* pipe = _popen(cmd.c_str(), "r");
        if (!pipe) throw runtime_error("cmd error");
        vector<string> list;
        for (char buffer[256]=""; !feof(pipe);) {
            if (fgets(buffer, sizeof(buffer), pipe) != NULL and buffer[0]!=0) {
                buffer[strlen(buffer)-1] = 0;
                //cout << buffer << endl;
                list.emplace_back(buffer);
            }
        }
        _pclose(pipe), pipe=nullptr;
        return list;
    }
    // 獲取清單(檔案+資料夾)
    static vector<string> getList(string path="", string param="") {
        const string sp=" ";
        string cmd = "dir";
        for (size_t pos=0; (pos=path.find("/")) != string::npos;)
            path.replace(pos, 1,"\\");
        auto&& cwd = exec("cd"); // 紀錄初始位置並前往
        if (path != "" and _chdir(path.c_str()))
            throw runtime_error("dir is no exist.");
        if (param == "") // 查詢結果
            param = "/a-s/b/s" + param;
        cmd = cmd + sp + param;
        auto&& result = exec(cmd);
        if (_chdir(cwd[0].c_str())) // 返回初始位置
            throw runtime_error("dir is no exist.");
        return result;
    }
    // 獲取檔案清單
    static vector<string> getFileList(const string& path, const string& param="") {
        return getList(path, "/a-d-s/b/s/on " + param);
    }
    // 獲取資料夾清單
    static vector<string> getDirList(const string& path, const string& param="") {
        return getList(path, "/ad-s/b/s/on " + param);
    }

};

void test_exec(const string& path) {
    cout << "------------------test_exec-------------------" << endl;
    if (path != "" and _chdir(path.c_str())) {
        throw runtime_error("dir is no exist.");
    } 
    auto v = FileList::exec("dir /a-d/b/s/on *.*");
    for (auto&& i : v) {
        cout << i << endl;
    }
    cout << "---------------------------------------------" << endl;
}
void test_getList(const string& dir) {
    vector<string> v;
    // 第一個參數是路徑,留空預設是當前工作目錄
    cout << "----------------test_getList-----------------" << endl;
    v = FileList::getList(dir);                    // 獲取檔案清單(資料+檔案)
    for (auto&& i : v) cout << i << endl;
    cout << "---------------------------------------------" << endl;
    v = FileList::getFileList(dir);            // 獲取檔案(不包含資料夾)
    for (auto&& i : v) cout << i << endl;
    cout << "---------------------------------------------" << endl;
    v = FileList::getDirList(dir);                // 獲取資料夾(不包含檔案)
    for (auto&& i : v) cout << i << endl;
    cout << "---------------------------------------------" << endl;
    v = FileList::getFileList(dir, "*.txt");    // 獲取特定檔案
    for (auto&& i : v) cout << i << endl;
    cout << "---------------------------------------------" << endl;
}
//============================================================================
int main(int argc, char const* argv[]) {
    const char* dir0 = "";
    const char* dir = "Z:\\a";
    test_exec(dir);
    test_getList(dir);
    return 0;
}
//============================================================================

沒有留言:

張貼留言