Std :: string LPCSTR'ye nasıl dönüştürülür?


111

Nasıl bir dönüştürebilir std::stringiçin LPCSTR? Ayrıca, nasıl bir dönüştürebilir std::stringiçin LPWSTR?

Bunlarla tamamen kafam karıştı LPCSTR LPSTR LPWSTRve LPCWSTR.

Are LPWSTRve LPCWSTRaynı?

Yanıtlar:


114

str.c_str()Size bir verir const char *bir olan LPCSTR(sabit dize Long Pointer) - bir bir işaretçi olduğunu araçlarının 0karakter sonlandırıldı dize. Wgeniş dize anlamına gelir ( wchar_tyerine oluşur char).


5
Küçük seçici nokta: x64 LPCSTR üzerinde, (sabit) boş sonlandırılmış bir dizeye 64 bitlik bir işaretçi olacaktır.
Joel

154

Çağrı c_str()bir olsun const char *( LPCSTRbir itibaren) std::string.

Hepsi adında:

LPSTR - (uzun) dizeye işaretçi - char *

LPCSTR - (uzun) sabit dizeye işaretçi - const char *

LPWSTR - (uzun) Unicode (geniş) dizgesine işaretçi - wchar_t *

LPCWSTR - (uzun) sabit Unicode (geniş) dizgesine işaretçi - const wchar_t *

LPTSTR - (uzun) işaretçi TCHAR (UNICODE tanımlıysa Unicode, tanımlanmamışsa ANSI) string - TCHAR *

LPCTSTR - (uzun) sabit TCHAR dizesine işaretçi - const TCHAR *

Adların L (uzun) kısmını göz ardı edebilirsiniz - bu, 16 bit Windows'tan gelen bir engeldir.


32

Bunlar, aşağıdakilere karşılık gelen Microsoft tarafından tanımlanan türlerdir:

LPCSTR: boş sonlandırılmış const dizesine işaretçi char

LPSTR: boş sonlandırılmış karakter dizgesine işaretçi char(genellikle bir tampon geçirilir ve bir 'çıktı' parametresi olarak kullanılır)

LPCWSTR: const'ın boş sonlandırılmış dizesine işaretçi wchar_t

LPWSTR: boş sonlandırılmış dizeye işaretçi wchar_t(genellikle bir tampon geçirilir ve bir 'çıkış' parametresi olarak kullanılır)

std::stringA'yı bir LPCSTR'ye "dönüştürmek" tam içeriğe bağlıdır, ancak genellikle çağırmak .c_str()yeterlidir.

Bu çalışıyor.

void TakesString(LPCSTR param);

void f(const std::string& param)
{
    TakesString(param.c_str());
}

Böyle bir şey yapmaya kalkışmamalısın.

LPCSTR GetString()
{
    std::string tmp("temporary");
    return tmp.c_str();
}

Tarafından döndürülen tampon .c_str(), std::stringörneğe aittir ve yalnızca dizge bir sonraki değiştirilene veya yok edilene kadar geçerli olacaktır.

Bir dönüştürmek için std::stringbir karşı LPWSTRdaha karmaşıktır. Bir isteyen LPWSTRbir değiştirilebilir tampona ihtiyaç ve ayrıca sen anlamak emin olması gerektiğini ima kodlayan karakterstd::string kullanıyor. Eğer, std::stringsistem varsayılan kodlamasını kullanan bir dize içeriyorsa (burada pencereler varsayarak), gerekli geniş karakter arabelleğinin uzunluğunu bulabilir ve MultiByteToWideChar(bir Win32 API işlevi) kullanarak kod dönüştürmeyi gerçekleştirebilirsiniz .

Örneğin

void f(const std:string& instr)
{
    // Assumes std::string is encoded in the current Windows ANSI codepage
    int bufferlen = ::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), NULL, 0);

    if (bufferlen == 0)
    {
        // Something went wrong. Perhaps, check GetLastError() and log.
        return;
    }

    // Allocate new LPWSTR - must deallocate it later
    LPWSTR widestr = new WCHAR[bufferlen + 1];

    ::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), widestr, bufferlen);

    // Ensure wide string is null terminated
    widestr[bufferlen] = 0;

    // Do something with widestr

    delete[] widestr;
}

18

Kullanarak LPWSTR, gösterdiği dizinin içeriğini değiştirebilirsiniz. LPCWSTRSizi kullanarak gösterdiği dizenin içeriğini değiştiremezsiniz.

std::string s = SOME_STRING;
// get temporary LPSTR (not really safe)
LPSTR pst = &s[0];
// get temporary LPCSTR (pretty safe)
LPCSTR pcstr = s.c_str();
// convert to std::wstring
std::wstring ws; 
ws.assign( s.begin(), s.end() );
// get temporary LPWSTR (not really safe)
LPWSTR pwst = &ws[0];
// get temporary LPCWSTR (pretty safe)
LPCWSTR pcwstr = ws.c_str();

LPWSTRsadece orijinal dizeye bir göstericidir. Yukarıdaki örneği kullanarak onu işlevden döndürmemelisiniz. Geçici olmamak LPWSTRiçin, öbek üzerinde orijinal dizenin bir kopyasını almalısınız. Aşağıdaki örneği kontrol edin:

LPWSTR ConvertToLPWSTR( const std::string& s )
{
  LPWSTR ws = new wchar_t[s.size()+1]; // +1 for zero at the end
  copy( s.begin(), s.end(), ws );
  ws[s.size()] = 0; // zero at the end
  return ws;
}

void f()
{
  std::string s = SOME_STRING;
  LPWSTR ws = ConvertToLPWSTR( s );

  // some actions

  delete[] ws; // caller responsible for deletion
}

4

MultiByteToWideCharCharles Bailey verdiği cevabın doğru biridir. Çünkü LPCWSTRsadece bir typedef const WCHAR*, widestrbir yerde orada kullanılabilecek örnek kodda LPWSTRbeklenen ya da nerede birLPCWSTR bekleniyor.

Küçük bir ince ayar, std::vector<WCHAR>manuel olarak yönetilen bir dizi yerine kullanmak olacaktır :

// using vector, buffer is deallocated when function ends
std::vector<WCHAR> widestr(bufferlen + 1);

::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), &widestr[0], bufferlen);

// Ensure wide string is null terminated
widestr[bufferlen] = 0;

// no need to delete; handled by vector

Ayrıca, başlamak için geniş dizelerle çalışmanız gerekiyorsa, std::wstringbunun yerine kullanabilirsiniz std::string. Windows TCHARtipi ile çalışmak istiyorsanız kullanabilirsiniz std::basic_string<TCHAR>. 'Dan' std::wstringa LPCWSTRveya ' std::basic_string<TCHAR>a dönüştürmek LPCTSTRsadece bir arama meselesidir c_str. ANSI ve UTF-16 karakterleri arasında geçiş yaparken MultiByteToWideChar(ve tersi WideCharToMultiByte) resme girer.


3

Dönüşüm basittir:

std :: string str; LPCSTR lpcstr = str.c_str ();


3

Dönüştürmek basittir:

std::string myString;

LPCSTR lpMyString = myString.c_str();

Burada dikkat edilmesi gereken bir nokta, c_str'in myString'in bir kopyasını döndürmemesi, sadece std :: string'in sarmaladığı karakter dizgisine bir gösterici döndürmesidir. Bir kopya istiyorsanız / buna ihtiyacınız varsa strcpy kullanarak kendiniz bir tane oluşturmanız gerekir.


1

Bir dönüştürmek için en kolay yolu std::stringbir etmek LPWSTRBence geçerli:

  1. Dönüştürme std::stringa kadarstd::vector<wchar_t>
  2. Vektördeki ilkinin adresini alın wchar_t.

std::vector<wchar_t>std::string.begin()ve .end()yineleyiciler gibi iki yineleyici alacak şablonlu bir ctor'a sahiptir . Bu, her bir karakteri a'ya dönüştürecektir wchar_t. Bu std::string, Unicode değerlerinin Latin-1 değerlerine benzemesi nedeniyle yalnızca ASCII veya Latin-1 içeriyorsa geçerlidir . CP1252 veya başka herhangi bir kodlamadan karakterler içeriyorsa, daha karmaşıktır. Daha sonra karakterleri dönüştürmeniz gerekecek.


Neden kullanmıyorsun std::wstring?
Timmmm

@Timmmm: C ++ 11, uygulamalar eski kurallardan yararlanmadığı için şartnameyi sıkılaştırdı, bugün bu tamam olurdu.
MSalters

1
std::string myString("SomeValue");
LPSTR lpSTR = const_cast<char*>(myString.c_str());

MyString girdi dizedir ve LPSTR 's olan LPSTR eşdeğeri.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.