2011-04-26 44 views
1

我發現生成我的程序參數列表的最簡單方法是作爲字符串的向量。但是,execv需要第二個參數的一個字符數組。讓它接受字符串的最簡單方法是什麼?如何將字符串向量傳遞給execv

+3

你不能「讓它接受」任何它並沒有書面接受。但是,您可以將您的輸入轉換爲其理解的格式。 – 2011-04-26 23:59:16

回答

10

execv()只接受一個字符串指針數組。沒有辦法讓它接受任何其他的東西。它是一個標準接口,可以從每個託管語言調用,而不僅僅是C++。

我已經測試編譯此:

std::vector<string> vector; 
    const char *programname = "abc"; 

    const char **argv = new const char* [vector.size()+2]; // extra room for program name and sentinel 
    argv [0] = programname;   // by convention, argv[0] is program name 
    for (int j = 0; j < vector.size()+1; ++j)  // copy args 
      argv [j+1] = vector[j] .c_str(); 

    argv [vector.size()+1] = NULL; // end of arguments sentinel is NULL 

    execv (programname, (char **)argv); 
+1

由於將argv [0]設置爲程序名,因此它看起來像將程序名兩次傳遞給execv。 – 2011-04-27 00:08:42

+3

是的,'execv()'是如何工作的。 – wallyk 2011-04-27 00:13:12

+0

我從第一行收到各種錯誤。 – 2011-04-27 00:14:01

1

的原型execv是:

int execv(const char *path, char *const argv[]); 

這意味着參數列表指針爲空終止的C字符串的數組。

您有vector<string>。找出該矢量的大小並製作一個指向char的指針數組。然後循環遍歷向量,向量中的每個string都將數組的相應元素設置爲指向它。

+0

這種方法唯一的問題是'std :: string'存儲的數據通常沒有null結束符。在調用'execv()'之前,必須使用'std :: string :: c_str()'或者在向量手冊中的每個字符串中包含空終止符。 – Hydranix 2016-10-18 00:40:26

1

你不能改變的是如何execv作品(不容易反正),但你可以用一個工作方式重載函數名,你想讓它:

int execv(const string& path, const vector<string>& argv) { 
    vector<const char*> av; 
    for (vector<string>::const_iterator i = argv.begin(); i != argv.end(); ++i) 
     av.push_back(i->c_str()); 
    av.push_back(0); 
    return execv(path.c_str(), &av[0]); 
} 

當然,這可能會導致有些混亂。你最好給它一個除execv()之外的名字。

注意:我只是在我頭頂鍵入這個。它可能不起作用。它可能甚至不能編譯;-)

1

前段時間我偶然發現了同樣的問題。

我最終建立了參數列表std::basic_string<char const*>。然後,我調用c_str()方法,並對結果進行const_cast<char* const*>execv接受的格式獲取列表。

對於組成的參數,我new ed字符串(由普通字符組成的普通字符串;)),拿着它們的c_str(),讓它們泄漏。

const_cast需要除去額外const作爲給定字符串類型的c_str()方法返回一個char const* const* IIRC。打字,我想我可以使用std::basic_string<char*>,但我想我有一個理由...


我清楚地知道,const -casting和內存泄漏看起來有點粗魯,的確是不好的做法,但因爲execv取代了整個過程,它無論如何都不重要。

0

是的,它可以通過利用矢量使用的內部數組相當乾淨地完成。最好不要在向量中使用C++字符串,const_cast字符串文字和string.c_str()的char *。

這將工作,因爲標準保證它的元素被連續存儲(見https://stackoverflow.com/a/2923290/383983

#include <vector> 

using std::vector; 

int main() { 
    vector<char*> commandVector; 

    // do a push_back for the command, then each of the arguments 
    commandVector.push_back(const_cast<char*>("echo")); 
    commandVector.push_back(const_cast<char*>("testing")); 
    commandVector.push_back(const_cast<char*>("1")); 
    commandVector.push_back(const_cast<char*>("2")); 
    commandVector.push_back(const_cast<char*>("3")); 

    // push NULL to the end of the vector (execvp expects NULL as last element) 
    commandVector.push_back(NULL); 

    int status = execvp(command[0], &command[0]); 
    return 0; 
} 

做一個const_cast會避免「從字符串常量‘字符*’不贊成使用的轉換」。字符串文字在C++中被實現爲'const char *'。 const_cast是在這裏強制轉換的最安全的形式,因爲它只能刪除const並且不會做其他有趣的事情。無論如何,execvp不會編輯這些值。

如果你想避免所有的強制轉換,你必須將所有的值複製到'char *'類型並不真正值得複雜化。

但如果你想要的參數個數傳遞給execv/EXECL是已知的,它更容易在C.寫這篇

相關問題