2013-09-05 17 views
5

Mam ciągi wejściowe, które zawierają tylko cyfry (tylko zwykłe łacińskie, 0-9, więc na przykład "0123"), przechowywane jako std :: wstring i potrzebuję każdy jako znak *. Jaki jest najlepszy sposób, aby to zrobić? To jest moje pierwsze podejście:Konwersja std :: wstepna na char * z wcstombs_s

void type::convertWStringToCharPtr(_In_ std::wstring input, _Out_ char * outputString) 
{ 
    outputString = new char[outputSize]; 
    size_t charsConverted = 0; 
    const wchar_t * inputW = input.c_str(); 
    wcstombs_s(&charsConverted, outputString, sizeof(outputString), inputW, input.length()); 
} 

EDYCJA: Poniższy kod działa. Dziękuje wszystkim!

void type::convertWStringToCharPtr(_In_ std::wstring input, _Out_ char * outputString) 
{ 
    size_t outputSize = input.length() + 1; // +1 for null terminator 
    outputString = new char[outputSize]; 
    size_t charsConverted = 0; 
    const wchar_t * inputW = input.c_str(); 
    wcstombs_s(&charsConverted, outputString, outputSize, inputW, input.length()); 
} 
+2

sizeof (outputstring) robi to, co u think robi; mówi, jak duży jest wskaźnik – pm100

+0

Dzięki, zaktualizowałem kod. Pomyślałem, że z jakiegoś powodu wcstombs_s chciał mieć rozmiar wskaźnika. –

+0

I nadal nie działa? –

Odpowiedz

10

nie przeznaczają wystarczającej ilości pamięci do bufora:

char * outputString = new char[input.length()]; 

Powinny być

char * outputString = new char[input.length() + 1]; 

powodu kończącego NUL znaków.

Och, a także, zgodnie z komentarzem pm100: sizeof(outputString) podaje rozmiar wskaźnika. Powinieneś użyć input.length() + 1, ponieważ jest to rozmiar bufora.

5

W kodzie jest kilka błędów. Po pierwsze, nie przydzielasz wystarczającej ilości miejsca w buforze docelowym dla znaku NULL. Musisz nadać co najmniej input.length() + 1 znaków, aby funkcja odniosła sukces.

Po drugie, nie przekazujesz tej funkcji prawidłowego rozmiaru bufora wyjściowego. sizeof(outputString) zwraca rozmiar samego outputString, czyli char *, a nie liczbę bajtów wskazywanych przez ten wskaźnik.

Więc funkcja powinna wyglądać następująco:

void CoverageTileManager::convertWStringToCharPtr(_In_ std::wstring input, _Out_ char * outputString) 
{ 
    size_t outputSize = input.length() + 1; 
    outputString = new char[outputSize]; 
    size_t charsConverted = 0; 
    wcstombs_s(&charsConverted, outputString, outputSize, input.c_str(), input.length()); 
    // TODO verify charsConverted = outputSize 
} 
1

W C++ nigdy nie używać czystych wskazówek: używać vector jeśli tablica char potrzebne w kupie! Czy chcesz skopiować ciąg źródłowy? Jeśli nie, należy podać odniesienie do stałej dla input. wcstombs_s jest używany tylko w systemie Windows, więc dlaczego nie używać po prostu WideCharToMultiByte? Czy sukces konwersji? Zwróć wartość.

bool CoverageTileManager::convertWStringToCharPtr(const std::wstring& input, std::vector<char>& outputString) 
{ 
    if (input.empty()) { 
     return false; 
    } 
    int size = WideCharToMultiByte(CP_ACP,0,input.c_str(),input.size(),NULL,0,NULL,NULL); 
    if (size <= 0) { 
     return false; 
    } 
    outputString.resize(size+1); 
    if (WideCharToMultiByte(CP_ACP,0,input.c_str(),input.size(),&outputString[0],size,NULL,NULL) <= 0) { 
     outputString.clear(); 
     return false; 
    } 
    outputString[size] = '\0'; 
    return true; 
} 

Zastosowanie wektora do zewnętrznego C++ lib:

extern void call(const char*, size_t); 
std::vector<char> buffer; 
std::wstring input; 
... 
if (convertWStringToCharPtr(input,buffer)) { 
    call(&buffer[0],buffer.size()); 
} 
+0

Nie mam wyboru co do typu znaku * - jest to wymagane przez zewnętrzną bibliotekę, z którą utknąłem. Gdybym miał swoją drogę, musiałby po prostu przyjąć std :: wstring, doskonale nadający się do pracy, którą wykonuje, a konwersja nie byłaby konieczna. –

+0

@ fatcat1111: Nie mogę uwierzyć w ten projekt: pobierz 'wstring' i użyj łańcucha w stylu C jako celu. Dziwne. Biedny! :) – Naszta

+0

@ fatcat1111: wektor może być używany jako zewnętrzny dla funkcji C lub C++. – Naszta

Powiązane problemy