Skip to content

Commit f9dfafe

Browse files
author
Colin Robertson
authored
Merge pull request #3852 from MicrosoftDocs/main637865041929172794
Repo sync for protected CLA branch
2 parents 6d0891e + badb2d4 commit f9dfafe

File tree

1 file changed

+73
-52
lines changed

1 file changed

+73
-52
lines changed

docs/text/how-to-convert-between-various-string-types.md

Lines changed: 73 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,30 @@
22
description: "Learn more about: How to: Convert Between Various String Types"
33
title: "How to: Convert Between Various String Types"
44
ms.custom: "get-started-article"
5-
ms.date: "11/04/2016"
5+
ms.date: 04/21/2022
66
helpviewer_keywords: ["converting string types", "string conversion [C++]", "strings [C++], converting"]
7-
ms.assetid: e7e4f741-3c82-45f0-b8c0-1e1e343b0e77
87
---
9-
# How to: Convert Between Various String Types
8+
# How to: Convert between various string types
109

11-
This topic demonstrates how to convert various Visual C++ string types into other strings. The strings types that are covered include `char *`, `wchar_t*`, [_bstr_t](../cpp/bstr-t-class.md), [CComBSTR](../atl/reference/ccombstr-class.md), [CString](../atl-mfc-shared/using-cstring.md), [basic_string](../standard-library/basic-string-class.md), and <xref:System.String?displayProperty=fullName>. In all cases, a copy of the string is made when converted to the new type. Any changes made to the new string will not affect the original string, and vice versa.
10+
This article shows how to convert various Visual C++ string types into other strings.
1211

13-
## Example: Convert from char *
12+
The strings types that are covered include `char *`, `wchar_t*`, [`_bstr_t`](../cpp/bstr-t-class.md), [`CComBSTR`](../atl/reference/ccombstr-class.md), [`CString`](../atl-mfc-shared/using-cstring.md), [`basic_string`](../standard-library/basic-string-class.md), and <xref:System.String?displayProperty=fullName>.
13+
14+
In all cases, a copy of the string is made when converted to the new type. Any changes made to the new string won't affect the original string, and vice versa.
15+
16+
For more background information about converting narrow and wide strings, see [Converting between narrow strings and wide strings](#converting-between-narrow-and-wide-strings).
17+
18+
## Example: Convert from `char *`
1419

1520
### Description
1621

17-
This example demonstrates how to convert from a `char *` to the other string types listed above. A `char *` string (also known as a C style string) uses a null character to indicate the end of the string. C style strings usually require one byte per character, but can also use two bytes. In the examples below, `char *` strings are sometimes referred to as multibyte character strings because of the string data that results from converting from Unicode strings. Single byte and multibyte character (`MBCS`) functions can operate on `char *` strings.
22+
This example demonstrates how to convert from a `char *` to the string types listed above. A `char *` string (also known as a C-style string) uses a null character to indicate the end of the string. C-style strings usually require 1 byte per character, but can also use 2 bytes. In the examples below, `char *` strings are sometimes referred to as multibyte character strings because of the string data that results from converting from wide Unicode strings. Single byte and multibyte character (`MBCS`) functions can operate on `char *` strings.
1823

1924
### Code
2025

2126
```cpp
2227
// convert_from_char.cpp
23-
// compile with: /clr /link comsuppw.lib
28+
// compile with: /clr /Zc:twoPhase- /link comsuppw.lib
2429

2530
#include <iostream>
2631
#include <stdlib.h>
@@ -35,7 +40,7 @@ using namespace System;
3540

3641
int main()
3742
{
38-
// Create and display a C style string, and then use it
43+
// Create and display a C-style string, and then use it
3944
// to create different kinds of strings.
4045
char *orig = "Hello, World!";
4146
cout << orig << " (char *)" << endl;
@@ -58,39 +63,39 @@ int main()
5863
// Display the result and indicate the type of string that it is.
5964
wcout << wcstring << _T(" (wchar_t *)") << endl;
6065

61-
// Convert the C style string to a _bstr_t string.
66+
// Convert the C-style string to a _bstr_t string.
6267
_bstr_t bstrt(orig);
6368
// Append the type of string to the new string
6469
// and then display the result.
6570
bstrt += " (_bstr_t)";
6671
cout << bstrt << endl;
6772

68-
// Convert the C style string to a CComBSTR string.
73+
// Convert the C-style string to a CComBSTR string.
6974
CComBSTR ccombstr(orig);
7075
if (ccombstr.Append(_T(" (CComBSTR)")) == S_OK)
7176
{
7277
CW2A printstr(ccombstr);
7378
cout << printstr << endl;
7479
}
7580

76-
// Convert the C style string to a CStringA and display it.
81+
// Convert the C-style string to a CStringA and display it.
7782
CStringA cstringa(orig);
7883
cstringa += " (CStringA)";
7984
cout << cstringa << endl;
8085

81-
// Convert the C style string to a CStringW and display it.
86+
// Convert the C-style string to a CStringW and display it.
8287
CStringW cstring(orig);
8388
cstring += " (CStringW)";
8489
// To display a CStringW correctly, use wcout and cast cstring
8590
// to (LPCTSTR).
8691
wcout << (LPCTSTR)cstring << endl;
8792

88-
// Convert the C style string to a basic_string and display it.
93+
// Convert the C-style string to a basic_string and display it.
8994
string basicstring(orig);
9095
basicstring += " (basic_string)";
9196
cout << basicstring << endl;
9297

93-
// Convert the C style string to a System::String and display it.
98+
// Convert the C-style string to a System::String and display it.
9499
String ^systemstring = gcnew String(orig);
95100
systemstring += " (System::String)";
96101
Console::WriteLine("{0}", systemstring);
@@ -109,17 +114,17 @@ Hello, World! (basic_string)
109114
Hello, World! (System::String)
110115
```
111116

112-
## Example: Convert from wchar_t *
117+
## Example: Convert from `wchar_t *`
113118

114119
### Description
115120

116-
This example demonstrates how to convert from a `wchar_t *` to the other string types listed above. Several string types, including `wchar_t *`, implement wide character formats. To convert a string between a multibyte and a wide character format, you can use a single function call like `mbstowcs_s` or a constructor invocation for a class like `CStringA`.
121+
This example demonstrates how to convert from a `wchar_t *` to other string types. Several string types, including `wchar_t *`, implement wide character formats. To convert a string between a multibyte and a wide character format, you can use a single function call like `mbstowcs_s` or a constructor invocation for a class like `CStringA`.
117122

118123
### Code
119124

120125
```cpp
121126
// convert_from_wchar_t.cpp
122-
// compile with: /clr /link comsuppw.lib
127+
// compile with: /clr /Zc:twoPhase- /link comsuppw.lib
123128

124129
#include <iostream>
125130
#include <stdlib.h>
@@ -141,7 +146,7 @@ int main()
141146

142147
// Convert the wchar_t string to a char* string. Record
143148
// the length of the original string and add 1 to it to
144-
// account for the terminating null character.
149+
// account for the terminating NULL character.
145150
size_t origsize = wcslen(orig) + 1;
146151
size_t convertedChars = 0;
147152

@@ -154,7 +159,7 @@ int main()
154159
// character in the input string (including a wide character
155160
// null). Because a multibyte character can be one or two bytes,
156161
// you should allot two bytes for each character. Having extra
157-
// space for the new string is not an error, but having
162+
// space for the new string isn't an error, but having
158163
// insufficient space is a potential security problem.
159164
const size_t newsize = origsize*2;
160165
// The new string will contain a converted copy of the original
@@ -231,17 +236,17 @@ Hello, World! (basic_string)
231236
Hello, World! (System::String)
232237
```
233238

234-
## Example: Convert from _bstr_t
239+
## Example: Convert from `_bstr_t`
235240

236241
### Description
237242

238-
This example demonstrates how to convert from a `_bstr_t` to the other string types listed above. The `_bstr_t` object is a way to encapsulate wide character `BSTR` strings. A BSTR string has a length value and does not use a null character to terminate the string, but the string type you convert to may require a terminating null.
243+
This example demonstrates how to convert from a `_bstr_t` to other string types. The `_bstr_t` object encapsulates wide character `BSTR` strings. A `BSTR` string has a length value and doesn't use a null character to terminate the string, but the string type you convert to may require a terminating `NULL`.
239244

240245
### Code
241246

242247
```cpp
243248
// convert_from_bstr_t.cpp
244-
// compile with: /clr /link comsuppw.lib
249+
// compile with: /clr /Zc:twoPhase- /link comsuppw.lib
245250

246251
#include <iostream>
247252
#include <stdlib.h>
@@ -261,9 +266,9 @@ int main()
261266
_bstr_t orig("Hello, World!");
262267
wcout << orig << " (_bstr_t)" << endl;
263268

264-
// Convert the wide character _bstr_t string to a C style
269+
// Convert the wide character _bstr_t string to a C-style
265270
// string. To be safe, allocate two bytes for each character
266-
// in the char* string, including the terminating null.
271+
// in the char* string, including the terminating NULL.
267272
const size_t newsize = (orig.length()+1)*2;
268273
char *nstring = new char[newsize];
269274

@@ -329,17 +334,17 @@ Hello, World! (basic_string)
329334
Hello, World! (System::String)
330335
```
331336

332-
## Example: Convert from CComBSTR
337+
## Example: Convert from `CComBSTR`
333338

334339
### Description
335340

336-
This example demonstrates how to convert from a `CComBSTR` to the other string types listed above. Like _bstr_t, a `CComBSTR` object is a way to encapsulate wide character BSTR strings. A BSTR string has a length value and does not use a null character to terminate the string, but the string type you convert to may require a terminating null.
341+
This example demonstrates how to convert from a `CComBSTR` to other string types. Like `_bstr_t`, a `CComBSTR` object encapsulates wide character `BSTR` strings. A `BSTR` string has a length value and doesn't use a null character to terminate the string, but the string type you convert to may require a terminating `NULL`.
337342

338343
### Code
339344

340345
```cpp
341346
// convert_from_ccombstr.cpp
342-
// compile with: /clr /link comsuppw.lib
347+
// compile with: /clr /Zc:twoPhase- /link comsuppw.lib
343348

344349
#include <iostream>
345350
#include <stdlib.h>
@@ -366,7 +371,7 @@ int main()
366371
// Convert a wide character CComBSTR string to a
367372
// regular multibyte char* string. Allocate enough space
368373
// in the new string for the largest possible result,
369-
// including space for a terminating null.
374+
// including space for a terminating NULL.
370375
const size_t newsize = (orig.Length()+1)*2;
371376
char *nstring = new char[newsize];
372377

@@ -389,7 +394,7 @@ int main()
389394
wcscpy_s(wcstring, widesize, orig);
390395
wcscat_s(wcstring, widesize, strConcat);
391396

392-
// Display the result. Unlike CStringW, a wchar_t does not need
397+
// Display the result. Unlike CStringW, a wchar_t doesn't need
393398
// a cast to (LPCTSTR) with wcout.
394399
wcout << wcstring << endl;
395400

@@ -437,19 +442,19 @@ Hello, World! (basic_string)
437442
Hello, World! (System::String)
438443
```
439444

440-
## Example: Convert from CString
445+
## Example: Convert from `CString`
441446

442447
### Description
443448

444-
This example demonstrates how to convert from a `CString` to the other string types listed above. `CString` is based on the TCHAR data type, which in turn depends on whether the symbol `_UNICODE` is defined. If `_UNICODE` is not defined, `TCHAR` is defined to be char and `CString` contains a multibyte character string; if `_UNICODE` is defined, `TCHAR` is defined to be **`wchar_t`** and `CString` contains a wide character string.
449+
This example demonstrates how to convert from a `CString` to other string types. `CString` is based on the `TCHAR` data type, which in turn depends on whether the symbol `_UNICODE` is defined. If `_UNICODE` isn't defined, `TCHAR` is defined to be `char` and `CString` contains a multibyte character string; if `_UNICODE` is defined, `TCHAR` is defined to be **`wchar_t`** and `CString` contains a wide character string.
445450

446-
`CStringA` is the multibyte string always version of `CString`, `CStringW` is the wide character string only version. Neither `CStringA` nor `CStringW` use `_UNICODE` to determine how they should compile. `CStringA` and `CStringW` are used in this example to clarify minor differences in buffer size allocation and output handling.
451+
`CStringA` contains the `char` type and supports single-byte or multibyte strings. `CStringW` is the wide character version. `CStringA` and `CStringW` don't use `_UNICODE` to determine how they should compile. `CStringA` and `CStringW` are used in this example to clarify minor differences in buffer size allocation and output handling.
447452

448453
### Code
449454

450455
```cpp
451456
// convert_from_cstring.cpp
452-
// compile with: /clr /link comsuppw.lib
457+
// compile with: /clr /Zc:twoPhase- /link comsuppw.lib
453458

454459
#include <iostream>
455460
#include <stdlib.h>
@@ -579,17 +584,17 @@ Hello, World! (basic_string)
579584
Hello, World! (System::String)
580585
```
581586

582-
## Example: Convert from basic_string
587+
## Example: Convert from `basic_string`
583588

584589
### Description
585590

586-
This example demonstrates how to convert from a `basic_string` to the other string types listed above.
591+
This example demonstrates how to convert from a `basic_string` to other string types.
587592

588593
### Code
589594

590595
```cpp
591596
// convert_from_basic_string.cpp
592-
// compile with: /clr /link comsuppw.lib
597+
// compile with: /clr /Zc:twoPhase- /link comsuppw.lib
593598

594599
#include <iostream>
595600
#include <stdlib.h>
@@ -610,7 +615,7 @@ int main()
610615

611616
// Convert a wide character basic_string string to a multibyte char*
612617
// string. To be safe, we allocate two bytes for each character
613-
// in the original string, including the terminating null.
618+
// in the original string, including the terminating NULL.
614619
const size_t newsize = (strlen(orig.c_str()) + 1)*2;
615620
char *nstring = new char[newsize];
616621
strcpy_s(nstring, newsize, orig.c_str());
@@ -673,17 +678,17 @@ Hello, World! (CStringW)
673678
Hello, World! (System::String)
674679
```
675680

676-
## Example: Convert from System::String
681+
## Example: Convert from `System::String`
677682

678683
### Description
679684

680-
This example demonstrates how to convert from a wide character (Unicode) [System::String](/dotnet/api/system.string) to the other string types listed above.
685+
This example demonstrates how to convert from a wide character [System::String](/dotnet/api/system.string) to other string types.
681686

682687
### Code
683688

684689
```cpp
685690
// convert_from_system_string.cpp
686-
// compile with: /clr /link comsuppw.lib
691+
// compile with: /clr /Zc:twoPhase- /link comsuppw.lib
687692

688693
#include <iostream>
689694
#include <stdlib.h>
@@ -713,7 +718,7 @@ int main()
713718
// Make a copy of the System::String as a multibyte
714719
// char* string. Allocate two bytes in the multibyte
715720
// output string for every wide character in the input
716-
// string, including space for a terminating null.
721+
// string, including space for a terminating NULL.
717722
size_t origsize = wcslen(wch) + 1;
718723
const size_t newsize = origsize*2;
719724
size_t convertedChars = 0;
@@ -778,16 +783,32 @@ Hello, World! (CStringW)
778783
Hello, World! (basic_string)
779784
```
780785

786+
## Converting between narrow and wide strings
787+
788+
Legacy C and Windows apps use code pages rather than Unicode encodings when handling narrow strings and wide strings.
789+
790+
.NET strings are UTF-16, but ATL's `CStringA` is a narrow string, and the conversion from wide to narrow is performed by the [`WideCharToMultiByte`](/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte) Win32 function. When converting a C-style `CHAR*` (a C-style `CHAR*` is a .NET `byte*`) to a string, the opposite Win32 function, [`MultiByteToWideChar`](/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar) is called.
791+
792+
Both functions rely on the Windows concept of a code page; not the .NET concept of a culture. To change the system code page, use the region setting using **Control Panel** > enter `Region` into the search box > **Region (change date, time, or number formats)** > **Administrative** > **Change system locale**.
793+
794+
On an `en-US` language version of Windows, the code page defaults to 1033. If you install a different language of Windows, it will have a different code page. You can change it using the control panel.
795+
796+
There's a mismatch in the way that `CStringA` performs a wide to narrow conversion and the way that `gcnew string(CHAR*)` performs a narrow to wide conversion. `CStringA` passes `CP_THREAD_ACP`, which means to use the current *thread* code page, to the narrowing conversion method. But `string.ctor(sbyte*)` passes `CP_ACP`, which means to use the current *system* code page, to the widening conversion method. If the system and thread code pages don't match, it can cause round-trip data corruption.
797+
798+
To reconcile this difference, use the constant `_CONVERSION_DONT_USE_THREAD_LOCALE`) to get the conversion to use `CP_ACP` (like .NET) instead of `CP_THREAD_ACP`. For more information, see [_CONVERSION_DONT_USE_THREAD_LOCALE](https://social.msdn.microsoft.com/Forums/vstudio/en-US/f3820781-c418-40bf-8c4f-7250001e5b68/visual-studio-2015-update-1-implicit-string-narrow-wide-conversion-and).
799+
800+
Another approach is to use [`pinvoke`](/dotnet/standard/native-interop/pinvoke) to call [`GetThreadLocale`](/windows/win32/api/winnls/nf-winnls-getthreadlocale). Use the returned `LCID` to create a [`CultureInfo`](/dotnet/api/system.globalization.cultureinfo). Then use `CultureInfo.TextInfo` to get the code page to use in the conversion.
801+
781802
## See also
782803

783-
[ATL and MFC String Conversion Macros](../atl/reference/string-conversion-macros.md)<br/>
784-
[CString Operations Relating to C-Style Strings](../atl-mfc-shared/cstring-operations-relating-to-c-style-strings.md)<br/>
785-
[How to: Convert Standard String to System::String](../dotnet/how-to-convert-standard-string-to-system-string.md)<br/>
786-
[How to: Convert System::String to Standard String](../dotnet/how-to-convert-system-string-to-standard-string.md)<br/>
787-
[How to: Convert System::String to wchar_t* or char\*](../dotnet/how-to-convert-system-string-to-wchar-t-star-or-char-star.md)<br/>
788-
[Programming with CComBSTR](../atl/programming-with-ccombstr-atl.md)<br/>
789-
[mbstowcs_s, _mbstowcs_s_l](../c-runtime-library/reference/mbstowcs-s-mbstowcs-s-l.md)<br/>
790-
[wcstombs_s, _wcstombs_s_l](../c-runtime-library/reference/wcstombs-s-wcstombs-s-l.md)<br/>
791-
[strcpy_s, wcscpy_s, _mbscpy_s](../c-runtime-library/reference/strcpy-s-wcscpy-s-mbscpy-s.md)<br/>
792-
[strcat_s, wcscat_s, _mbscat_s](../c-runtime-library/reference/strcat-s-wcscat-s-mbscat-s.md)<br/>
793-
[pin_ptr (C++/CLI)](../extensions/pin-ptr-cpp-cli.md)
804+
[ATL and MFC string conversion macros](../atl/reference/string-conversion-macros.md)\
805+
[`CString` operations relating to C-style strings](../atl-mfc-shared/cstring-operations-relating-to-c-style-strings.md)\
806+
[How to: convert standard `String` to `System::String`](../dotnet/how-to-convert-standard-string-to-system-string.md)\
807+
[How to: convert `System::String` to standard `String`](../dotnet/how-to-convert-system-string-to-standard-string.md)\
808+
[How to: convert `System::String` to `wchar_t*` or `char*`](../dotnet/how-to-convert-system-string-to-wchar-t-star-or-char-star.md)\
809+
[Programming with `CComBSTR`](../atl/programming-with-ccombstr-atl.md)\
810+
[`mbstowcs_s, _mbstowcs_s_l`](../c-runtime-library/reference/mbstowcs-s-mbstowcs-s-l.md)\
811+
[`wcstombs_s, _wcstombs_s_l`](../c-runtime-library/reference/wcstombs-s-wcstombs-s-l.md)\
812+
[`strcpy_s, wcscpy_s, _mbscpy_s`](../c-runtime-library/reference/strcpy-s-wcscpy-s-mbscpy-s.md)\
813+
[`strcat_s, wcscat_s, _mbscat_s`](../c-runtime-library/reference/strcat-s-wcscat-s-mbscat-s.md)\
814+
[`pin_ptr` (C++/CLI)](../extensions/pin-ptr-cpp-cli.md)

0 commit comments

Comments
 (0)