[英]C++: From stringstream to char**
我有一個帶有parse(int argc, char* argv[])
函數的類,我必須使用它來設置對象的所需狀態。 我使用stringstream
從gui中獲取參數,然后嘗試將它們轉換為char **以將其傳遞給函數。 這是我得到的:
std::stringstream sstream;
sstream << "-clip" << " " << min_x_entry.get_text()
<< " " << max_x_entry.get_text(); // etc.
std::cout << sstream.str(); // All looks good here
std::vector<std::string> args;
std::vector<char*> argv;
std::string arg;
while (sstream >> arg)
{
args.push_back(arg);
argv.push_back(const_cast<char*>(args.back().c_str()));
}
argv.push_back(0);
int argc = args.size();
for (int i = 0; i < argc; ++i)
std::cout << &argv[0][i]; // This outputs garbage
my_object.parse(argc, &argv[0]) // And this fails
我想念什么? 有沒有更好的方法來實現這一目標?
一個問題是args
向量的重新分配,因為push_back()
會在必要時增大向量的大小:
如果new size()不大於Capacity(),則沒有迭代器或引用無效。 否則,所有迭代器和引用都將無效。
argv
向量在args
存儲了指向元素內部的指針,因此這些指針將失效。
一種解決方案是先創建args
向量,然后再創建argv
向量:
while (sstream >> arg) args.push_back(arg);
for (auto i = args.begin(); i != args.end(); i++)
{
argv.push_back(const_cast<char*>(i->c_str()));
}
argv.push_back(0);
打印出argv
字符串的for
循環不正確。 這個:
&argv[0][i]
是一個char*
但從argv
第一個條目的第i
個元素開始。 例如,如果argv
的第一個c字符串是"string"
:
&argv[0][1] is "tring"
&argv[0][2] is "ring"
改成:
for (int i = 0; i < argc; i++)
std::cout << argv[i] << std::endl; // Added 'endl' to flush 'cout'.
std::vector<std::string> args;
std::vector<char*> argv;
/* ... */
argv.push_back(const_cast<char*>(args.back().c_str()));
這里有很多問題。
string
的非const
成員函數之后,不能保證c_str()
返回的指針有效。 從c_str()
返回的指針通常不應該在以后存儲和使用,尤其是當您不確定其他代碼是否會調用string
的非const
成員時。 const_cast
荷蘭國際集團的const
-nedd從返回的指針遠c_str()
。 演員表本身是合法的,如果不是反模式的話。 但是,如果以后再嘗試修改存儲在該指針處的數據,那就是未定義行為。 這是標准對c_str()
:
const charT* c_str() const;
1 /返回:指向長度為size()+ 1的數組的初始元素的指針,其第一個size()元素等於* this控制的字符串的相應元素,而最后一個元素為charT()指定的空字符。
2 /要求:程序不得更改數組中存儲的任何值。 在隨后調用基本Basic字符串類的非常量成員函數並指定與此對象之后,程序也不會將返回值視為有效的指針值。 const charT * data()const;
3 /返回:如果size()不為零,則該成員返回一個指向數組初始元素的指針,該數組的第一個size()元素等於由* this控制的字符串的相應元素。 如果size()為零,則該成員返回一個非空指針,該指針是可復制的,並且可以添加零。
4 /要求:程序不得更改存儲在字符數組中的任何值。 在隨后調用basic_string的非const成員函數並指定與此相同的對象之后,程序也不會將返回的值視為有效的指針值。 allocator_type get_allocator()const;
5 /返回:用於構造字符串的Allocator對象的副本。
您忘記了在循環中初始化變量i
。 並且您試圖僅打印出矢量argv
的第一項。
for (int i = 0; i < argc; ++i)
std::cout << argv[i];
您可以擺脫const_cast
而不必擔心parse()
方法可能通過執行以下操作來修改參數:
std::vector<std::vector<char>> args;
std::for_each(std::istream_iterator<std::string>(sstream),
std::istream_iterator<std::string>(),
[&args](const std::string& str)
{
std::vector<char> temp(str.begin(), str.end());
temp.push_back('\0');
args.push_back(temp);
});
std::vector<char*> argv(args.size());
for (auto& v : args) argv.push_back(v.data());
my_object.parse(argv.size(), argv.data());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.