我有一个带有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我错过了什么? 有没有更好的方法来实现这一目标?
I have a class with parse(int argc, char* argv[]) function which I have to use to set a desired state of an object. I'm taking the parameters from the gui using stringstream and then I'm trying to convert them to char** to pass them to the function. Here's what I've got:
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 failsWhat am I missing? Is there a better way of achieving this?
最满意答案
问题是重新分配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'.A problem would be reallocation of the args vector as push_back() will grow the size of the vector if required:
If new size() is not larger than capacity(), no iterators or references are invalidated. Otherwise all iterators and references are invalidated.
The argv vector is storing pointers to the internals of elements in args, so these would be invalidated.
A solution would be to create the args vector first then create the argv vector afterwards:
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);The for loop that prints out the argv strings is incorrect. This:
&argv[0][i]is a char* but starts from ith element of the first entry in argv. For example, if the first c-string in argv was "string":
&argv[0][1] is "tring" &argv[0][2] is "ring"change to:
for (int i = 0; i < argc; i++) std::cout << argv[i] << std::endl; // Added 'endl' to flush 'cout'.更多推荐
发布评论