벡터 를 char** C++ 로 변환
나는 있습니다vector<std::string>변수.나는 그것을 수용하는 방법으로 전달할 필요가 있습니다.char**입력 매개 변수로 사용할 수 있습니다.
가능하면 쓰기 가능한 파일을 전달해야 합니다.
업데이트 1: 서비스 메서드를 만드는 도구에서 매개 변수를 std::vector로 지정하지만, 수식자를 자동으로 &로 설정하므로 도구에서 생성된 메서드 정의는 다음과 같습니다.
std::string SvcImpl::myMethodname ( const std::string par1, const std::vector< std::string >& par2, const std::vector< std::string >& par3 )
{
}
이 메서드는 데이터 매개 변수의 값이 전달된 상태에서 자동으로 호출됩니다.이제 이 메서드 내부에서 lib 폴더의 dll에 있는 메서드를 호출합니다. 다음과 같습니다.
int method_to_be_called(char* par1, char ** par2, char ** par3, void* pRetValue);
파1 --> (char*)파1.c_str()에 합격합니다.
par2와 par3의 변수와 pRetValue의 변수를 전달하는 방법을 알아야 합니다. par2와 par3의 값은 벡터로 사용할 수 있지만 마지막 매개 변수 pRetValue는 std::string으로 반환해야 하는 출력 매개 변수입니다.
제가 매우 혼란스럽거나 매우 기본적인 질문을 한다면 죄송합니다.
모든 것을 복사하지 않고 문제를 해결하는 것이 가능합니다.std::strings함수가 전달된 내용을 수정하지 않는 한char**그렇지 않으면 모든 것을 새 char**' 구조로 복사하는 것 외에는 대안이 없습니다(두 번째 예 참조).
void old_func(char** carray, size_t size)
{
for(size_t i = 0; i < size; ++i)
std::cout << carray[i] << '\n';
}
int main()
{
std::vector<std::string> strings {"one", "two", "three"};
std::vector<char*> cstrings;
cstrings.reserve(strings.size());
for(size_t i = 0; i < strings.size(); ++i)
cstrings.push_back(const_cast<char*>(strings[i].c_str()));
// Do not change any of the strings here as that will
// invalidate the new data structure that relies on
// the returned values from `c_str()`
//
// This is not an issue after C++11 as long as you don't
// increase the length of a string (as that may cause reallocation)
if(!cstrings.empty())
old_func(&cstrings[0], cstrings.size());
}
예 2: 함수가 전달된 데이터를 수정해야 하는 경우:
void old_func(char** carray, size_t size)
{
for(size_t i = 0; i < size; ++i)
std::cout << carray[i] << '\n';
}
int main()
{
{
// pre C++11
std::vector<std::string> strings {"one", "two", "three"};
// guarantee contiguous, null terminated strings
std::vector<std::vector<char>> vstrings;
// pointers to rhose strings
std::vector<char*> cstrings;
vstrings.reserve(strings.size());
cstrings.reserve(strings.size());
for(size_t i = 0; i < strings.size(); ++i)
{
vstrings.emplace_back(strings[i].begin(), strings[i].end());
vstrings.back().push_back('\0');
cstrings.push_back(vstrings.back().data());
}
old_func(cstrings.data(), cstrings.size());
}
{
// post C++11
std::vector<std::string> strings {"one", "two", "three"};
std::vector<char*> cstrings;
cstrings.reserve(strings.size());
for(auto& s: strings)
cstrings.push_back(&s[0]);
old_func(cstrings.data(), cstrings.size());
}
}
참고: 더 나은 코드를 제공하도록 수정되었습니다.
갈릭의 대답은 많은 안전 문제를 가지고 있습니다.다음은 현대 C++에서 제가 수행하는 방법입니다.
#include <iostream>
#include <string>
#include <vector>
void old_func(char** carray, std::size_t size)
{
for(std::size_t i(0); i < size; ++i)
std::cout << carray[i] << '\n';
}
void other_old_func(const char** carray, std::size_t size)
{
for(std::size_t i(0); i < size; ++i)
std::cout << carray[i] << '\n';
}
int main()
{
{
std::cout << "modifiable version\n";
std::vector<std::string> strings{"one", "two", "three"};
std::vector<char*> cstrings{};
for(auto& string : strings)
cstrings.push_back(&string.front());
old_func(cstrings.data(), cstrings.size());
std::cout << "\n\n";
}
{
std::cout << "non-modifiable version\n";
std::vector<std::string> strings{"four", "five", "six"};
std::vector<const char*> cstrings{};
for(const auto& string : strings)
cstrings.push_back(string.c_str());
other_old_func(cstrings.data(), cstrings.size());
std::cout << std::endl;
}
}
엉망인 메모리 관리 또는 유해한 메모리 관리 없음const_casts.
출력:
modifiable version
one
two
three
non-modifiable version
four
five
six
이 질문에 대한 상위 등급의 답변은 사용자가 char** 매개 변수와 함께 한 크기로 전달해야 합니다.그러나 method_to_be_called()에서는 par2와 par3의 크기를 전달할 방법이 없으므로 이러한 c-style 문자열 목록은 아마도 null 종료될 것으로 예상됩니다.즉, 문자열 목록의 마지막 문자열(char*)은 null 포인터여야 합니다.이것은 많은 C 라이브러리에서 일반적인 패러다임입니다.
int method_to_be_called(char* par1, char ** par2, char ** par3, void* pRetValue);
이 문제를 해결하는 가장 편리한 방법은 아마도 좀 더 c 스타일의 답변을 사용하는 것입니다.
//directly create char** par2
std::vector<std::string> par2Vect{"one", "two", "three"};
char ** par2 = (char**) malloc( sizeof(char*)*(par2Vect.size() + 1) );
for(size_t i = 0; i < par2Vect.size(); ++i)
{
par2[i] = strdup(par2Vect[i].c_str());
}
// set the last entry to null to signify the end of the list
par2[par2Vect.size()] = nullptr;
// call your library
method_to_be_called(..., par2,...);
// delete par2
for(size_t i = 0; i < par2Vect.size(); ++i)
{
// free memory for each c-style string
free(par2[i]);
}
// free memory for outer char* array
free(par2);
저는 이것이 상당히 쉽고 너무 복잡하지 않고 수행될 수 있다고 믿습니다.
std::vector<std::string> vector = {"a", "std::vector", "of", "std::string"};
// Result char**.
char** result = new char*[vector.size()];
for (int index = 0; index < vector.size(); index++) {
result[index] = const_cast<char*>(vector[index].c_str());
}
// Use the result.
delete[] result;
// Deallocate the memory from heap after usage.
언급URL : https://stackoverflow.com/questions/26032039/convert-vectorstring-into-char-c
'programing' 카테고리의 다른 글
| Ajax(jquery 없음)로 멀티파트/폼 데이터 양식 콘텐츠를 보내는 방법은 무엇입니까? (0) | 2023.09.03 |
|---|---|
| MariaDB Azure에서 표준 시간대를 어떻게 구성합니까? (0) | 2023.09.03 |
| 혼란스러운 유형 정의 문법 이해 (0) | 2023.09.03 |
| Macos에서 Xampp를 10.1.36-MariaDB에서 10.2로 업데이트 (0) | 2023.09.03 |
| .replace 와 -replace in powershell의 차이점은 무엇입니까? (0) | 2023.09.03 |