簡體   English   中英

將std :: string轉換為char * const *的數組

[英]Turn std::string into array of char* const*'s

我正在使用POSIX api在C ++中編寫命令shell,並遇到了麻煩。 我正在通過execvp(3)執行,所以我不知何故需要將包含該命令的std :: string轉換為可以傳遞給的一個合適的char * consts *數組:

int execvp(const char *file, char *const argv[]);

我已經絞盡腦汁待了幾個小時,但我想不出任何現實或理智的方式來做這件事。 任何有關如何實現此轉換的幫助或見解將不勝感激。 謝謝你,有一個美好的一天!

編輯:根據Chnossos的要求,這是一個例子:

const char *args[] = {"echo", "Hello,", "world!"};
execvp(args[0], args);

假設你有一個包含多於“一個參數”的字符串,你首先必須拆分字符串(使用std::vector<std::string>可以存儲單獨的字符串),然后對於每個元素vector,將該字符串的.c_str()存儲到const char args[MAXARGS] [或std::vector<const char*> args; 如果你不介意使用C ++ 11,請使用args.data() 不要忘記在最后一個元素中存儲0nullptr

如果你使用c_str ,那么你所基於的字符串不是臨時字符串是至關重要的: const char* x = str.substr(11, 33).c_str(); 不會給你你想要的東西,因為在該行的末尾,臨時字符串被銷毀,其存儲空間被釋放。

如果你只有一個實際的參數,

const char* args[2] = { str.c_str(), 0 }; 

會工作。

示例方法:

#include <string>
#include <vector>
#include <cstring>

using namespace std;

int execvp(const char *file, char *const argv[]) {
   //doing sth
}

int main() {

   string s = "echo Hello world!";
   char* cs = strdup(s.c_str());
   char* lastbeg = cs;
   vector<char *> collection;
   for (char *itcs = cs; *itcs; itcs++) {
      if (*itcs == ' ') {
          *itcs = 0;
          collection.push_back(lastbeg);
          lastbeg = itcs + 1;
      }
   }
   collection.push_back(lastbeg);
   for (auto x: collection) {
       printf("%s\n", x);
   }
   execvp("abc.txt", &collection[0]);

}

請注意,此處未釋放cs的內存...在您的應用程序中,您需要處理...

可以從collection.size()簡單地提取數組中的元素數量

我用這個:

command_line.hpp:

#pragma once

#include <vector>
#include <string>

namespace wpsc { namespace unittest { namespace mock {

    class command_line final
    {
    public:
        explicit command_line(std::vector<std::string> args = {});
        explicit command_line(int argc, char const * const * const argv);

        int argc() const;

        /// @remark altering memory returned by this function results in UB
        char** argv() const;

        std::string string() const;
    private:
        std::vector<std::string> args_;
        mutable std::vector<char*> c_args_;
    };

}}} // wpsc::unittest::mock

command_line.cpp:

#include <wpsc/unittest/mock/command_line.hpp>

#include <algorithm>
#include <sstream>

namespace wpsc { namespace unittest { namespace mock {

    command_line::command_line(std::vector<std::string> args)
    : args_( std::move(args) ), c_args_( )
    {
    }

    command_line::command_line(int argc, char const * const * const argv)
    : command_line{ std::vector<std::string>{ argv, argv + argc } }
    {
    }

    int command_line::argc() const
    {
        return static_cast<int>(args_.size());
    }

    char ** command_line::argv() const
    {
        if(args_.empty())
            return nullptr;
        if(c_args_.size() != args_.size() + 1)
        {
            c_args_.clear();
            using namespace std;
            transform(begin(args_), end(args_), back_inserter(c_args_),
                [](const std::string& s) { return const_cast<char*>(s.c_str()); }
            );
            c_args_.push_back(nullptr);
        }
        return c_args_.data();
    }

    std::string command_line::string() const
    {
        using namespace std;
        ostringstream buffer;
        copy(begin(args_), end(args_), ostream_iterator<std::string>{ buffer, " " });
        return buffer.str();
    }

}}} // wpsc::unittest::mock

客戶代碼:

int main(int argc, char** argv)
{
    wpsc::unittest::mock::command_line cmd1{ argc, argv };
    // wpsc::unittest::mock::command_line cmd2{ {"app.exe" "-h"} };

    some_app_controller c;
    return c.run(cmd1.argc(), cmd1.argv());
}

如果解析實際上可能真的很復雜,我會選擇這樣的東西:

std::string cmd = "some really complicated command here";
char * const args[] =
{
    "sh",
    "-c",
    cmd.c_str(),
    (char *) NULL
};
execvp(args[0], args);

所以問題是將行拆分為單個參數,並用相應的指針填充參數向量?

假設您要在行中的空白處拆分,則使用空字節(就地)替換字符串中的空格。 然后,您可以使用指向字符串的指針填充參數向量。

您必須編寫一個循環來遍歷字符串。

您需要確定shell的規則並實現它們。 這是制作shell的重要部分。

你需要編寫這段代碼,這並不簡單。 在典型的shell中, echo "Hello world!" 必須成為{ echoHello world! ,而echo \\"Hello world!\\"必須成為{ echo"Hello world!" }。 等等。

什么會"在你的殼呢?會有什么'嗎?你需要做這些決定之前,這部分代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM