как передать вектор строки в foo (char const * const * const)? - PullRequest
8 голосов
/ 21 мая 2010

Редактировать: После реализации предложения Джеймса Хопкина, я все еще получаю предупреждения о "недопустимом имени" нуль "", что намного лучше, чем эти странные символы. Затем я вернулся и снова прочитал документ библиотеки, и оказалось, что для этой конкретной функции в ее аргументе должен быть еще один элемент не-NULL-строки, чем размер aNames. Эта дополнительная строка имеет другое назначение. После добавления еще одной строки код работает нормально. Это моя вина, и мне очень жаль.

Оригинальный пост:

Привет,

Это мой первый пост, поэтому, пожалуйста, будьте милы. Я искал в этом форуме и гуглил, но до сих пор не могу найти ответ. Эта проблема беспокоила меня больше суток, поэтому, пожалуйста, помогите мне. Спасибо.

Мне нужно передать вектор строки в библиотечную функцию foo (char const * const * const). Я не могу передать & Vec [0], так как это указатель на строку. Поэтому у меня есть массив, и я передаю c_str () в этот массив. Вот мой код (aNames - вектор строки):

const char* aR[aNames.size()];

std::transform(aNames.begin(), aNames.end(), aR, 
                boost::bind(&std::string::c_str, _1));
foo(aR);

Однако, кажется, что это вызывает некоторое неопределенное поведение:

Если я запускаю приведенный выше код, то функция foo выдает несколько предупреждений о недопустимых символах ('èI' blablabla) в aR.

Если я печатаю aR перед функцией foo следующим образом:

std::copy(aR, aR+rowNames.size(), 
          std::ostream_iterator<const char*>(std::cout, "\n"));
foo(aR);

Тогда все хорошо. Мои вопросы:

  1. Приводит ли преобразование к неопределенному поведению? Если так, то почему?

  2. Как правильно передать вектор строки в foo (char const * const * const)?

Ответы [ 3 ]

5 голосов
/ 21 мая 2010

Поскольку foo принимает только указатель, я предполагаю, что для этого требуется массив с нулевым символом в конце Выделите дополнительный элемент для aR и присвойте ему значение NULL.

Мое предложение будет:

std::vector<const char*> c_strings;
c_strings.reserve(aNames.size() + 1);

std::transform(
    aNames.begin(), aNames.end(),
    std::back_inserter(c_strings), 
    boost::bind(&std::string::c_str, _1)
    );

c_strings.push_back(0);
foo(&c_strings[0]);
1 голос
/ 21 мая 2010

Попробуйте это:

std::vector<char*> arr(aNames.size()+1); 
for(size_t i = 0; i < aNames.size(); ++i) 
    arr[i] = aNames[i].c_str();
arr[arr.size()-1] = NULL; // just in case
foo(&arr[0]);
1 голос
/ 21 мая 2010

Ну, мне кажется, это правильно. c_str создает массив символов с нулевым символом в конце, который является постоянным до следующей неконстантной строковой операции. Вы храните указатели c_str в массиве const char *.

Я не специалист по бусту, поэтому проблема может быть в этом, но я предполагаю, что ваши строки в векторе находятся в кодировке, несовместимой с кодировкой, ожидаемой в функции foo.

Проверьте ваш код с точки зрения кодирования.

my2c

...