C++. Покажчики. Частина 4. Покажчики і рядки символів. Використання покажчиків при перетворенні (конвертуванні) рядків




Покажчики. Частина 4. Покажчики і рядки символів. Використання покажчиків при перетворенні (конвертуванні) рядків

Дана тема базується на наступних темах:


Зміст


Пошук на інших ресурсах:

1. Як описати некерований покажчик (*) на рядковий літерал? Приклади

Детально про рядкові літерали описується тут.

Рядок символів представляє собою рядковий літерал, який є масивом елементів типу char. Адреса першого символу рядкового літералу є початковим значенням покажчика. Покажчик на перший елемент рядкового літералу є покажчиком на весь рядковий літерал.

Приклад. Покажчик на рядковий літерал. Спроба змінити символ в рядковому літералі.

// покажчик на рядковий літерал
char * ps2 = "This is a text - 2";

// доступ до елементу рядкового з допомогою покажчика
//*ps2 = 't'; - помилка, змінювати рядковий літерал через покажчик не можна

При спробі зміни значення символу рядкового літералу виникає помилка:

Attempted to read or write protected memory

2. Як описати покажчик на рядок, який описаний як масив символів? Приклад

Ім’я масиву символів є покажчиком-константою. Якщо рядок описано як масив символів, тоді можна змінювати символи рядка з допомогою покажчика.

Приклад. Покажчик на масив символів. Доступ до символу рядка, який описаний як масив символів.

// покажчик на масив символів
 char str1[] = "Text"; // масив str1 = { 'T', 'e', 'x', 't', '\0' }
 char *p1;

// спосіб 1 - ім'я рядка є покажчиком на перший символ рядка
p1 = str1; // покажчик p1 вказує на str1

// спосіб 2
p1 = &str1[0];

//доступ до символу рядка через покажчик
*p1 = 'N';     // str1 = "Next" - працює
*(p1+3) = '!'; // str1 = "Nex!"

3. Як з допомогою некерованого покажчика (*) отримати значення i-го елементу рядка символів? Приклад

Приклад. Читання символу в рядку символів з допомогою покажчика.

// читання символу рядкового літералу з допомогою покажчика
char * p1;
char c;
p1 = "Hello world!";

c = *p1;     // c = 'H'
c = *(p1+1); // c = 'e'
c = *(p1+2); // c = 'l'
c = *(p1+3); // c = 'l'

// читання символу масиву символів з допомогою покажчика
char * str = "Hello world!";
char * p2 = str;

c = *p2;      // c = 'H'
c = *(p2+1);  // c = 'e'
c = *(p2+12); // c = '\0'

4. Перетворення з char в String . Приклад використання керованого покажчика (^)

Для роботи з рядками символів мова C/C++ CLI підтримує клас System::String. У цьому класі є багато методів для зручного оперування рядками символів.

Для перетворення з типу char в тип String використовується керований покажчик ^.

Приклад 1. Перетворення з типу char* в тип String.

// перевід з char* в String
char * s = "Text";
String ^ str; // покажчик на клас System::String

str = gcnew String(s); // str = "Text"

Приклад 2. Перетворення з типу char[] в тип String.

#include <cstring>

...

// перевід з char[] в String
char s2[50];
strcpy(s2,"Text-2");

str = gcnew String(s2);

...

У вищенаведеному прикладі використана функція

strcpy(s2,"Text-2");

яка копіює рядок “Text-2” в рядок s2.

Щоб використовувати цю функцію потрібно підключити бібліотеку <cstring> або <string.h>.

5. Перетворення з wchar_t в String. Приклад використання керованого покажчика (^)

Тип wchar_t підтримує великі символьні набори, наприклад Unicode. Для перетворення з wchar_t в String доцільно використовувати керований покажчик ^.

Більш детально про особливості типу wchar_t в C/C++ CLI описується тут.






Приклад. Перетворення з wchar_t[] в String.

// перевід з wchar_t* в String
wchar_t * sw = L"Text Unicode";
String ^ str; // покажчик на клас System::String

str = gcnew String(sw); // перетворення

// перевід з wchar_t[] в String
wchar_t s2[] = L"Text Unicode";

6. Перетворення з string в System.String. Приклад використання керованого покажчика (^)

Мова C++ CLI підтримує тип string для роботи з рядками символів. Для перетворення з string в System.String використовується метод c_str().

Щоб використовувати тип string в програмах потрібно на початку модуля підключити бібліотеку <string> та простір імен std

#include <string>
using namespace std;

Приклад. Перетворення з string в System::String.

#include <string>
using namespace std;

...

// перетворення з string в System::String
string s = "Text";
String ^str = gcnew String(s.c_str()); // str = "Text"

7. Перетворення з String в char. Приклад використання керованого покажчика (^)

Перетворення відбувається в 2 етапи.
На першому етапі відбувається перетворення з типу String в тип wchar_t. Це здійснюється з допомогою функції

PtrToStringChars(s)

де s – рядок типу String. Функція PtrToStringChars() повертає об’єкт типу wchar_t.

На другому етапі відбувається перетворення з типу wchar_t в тип char. Це здійснюється з допомогою функції wcstombs(), яка отримує 5 параметрів. Нижче наведено опис функції wcstombs():

errno_t wcstombs_s(size_t * numChars, char * mbs, size_t size_mbs,
 const wchar_t *wcs, size_t len);

де

  • numChars – кількість символів, які вдалось сконвертувати (перетворити);
  • mbs – адреса буферу пам’яті, в який буде записано результат;
  • size_mbs – розмір буферу пам’яті для символів, що конвертуються;
  • wcs – рядок, який конвертується (вихідний рядок);
  • len – максимальна довжина вихідного рядка wcs або значення _TRUNCATE.

Тип size_t є результатом оператора sizeof() і складає довжину об’єкту.

Приклад.

// перетворення з String в char
String ^s = gcnew String("Text"); // вихідний рядок
char res[20]; // результуючий рядок

// 1. Перетворення з String в wchar_t
pin_ptr <const wchar_t> wstr = PtrToStringChars(s);

// 2. Перетворення з wchar_t в char[]
size_t d;
d = 0;
wcstombs_s(&d, res, (size_t)20, wstr, _TRUNCATE);

8. Перетворення з char в wchar_t. Приклад використання некерованого покажчика (*)

Приклад. Перетворення з char* у wchar_t*.

// перетворення (конвертування) з типу char* в тип wchar_t*
char *src = "Text-2"; // вихідний рядок
size_t src_size; // довжина вихідного рядка
size_t dest_size = 30; // буфер для рядка після перетворення
size_t res_size = 0; // довжина рядка після перетворення
wchar_t dest[30]; // результуючий рядок

src_size = strlen(src) + 1; // взяти довжину вихідного рядка + 1

// функція mbstowcs_s()
mbstowcs_s(&res_size, dest, src_size, src, _TRUNCATE); // dest = L"Text-2"

У вищенаведеному прикладі використано функцію

strlen(src)

яка реалізована в модулі <cstring> (або <string.h>). Функція повертає довжину рядка src.

Функція mbstowcs_s() отримує 5 параметрів і має опис:

errno_t mbstowcs_s(size_t *numChars, wchar_t *wcs, size_t size_wcs,
 const char *mbs, size_t len);

де

  • numChars – кількість символів, які вдалось сконвертувати (перетворити);
  • wcs – адреса буферу пам’яті, в який буде записано результат (тип wchar_t*);
  • size_wcs – розмір буферу пам’яті для символів, що конвертуються;
  • mbs – рядок, який конвертується (вихідний рядок);
  • len – максимальна довжина вихідного рядка mbs або значення _TRUNCATE.

Тип size_t є результатом оператора sizeof() і складає довжину об’єкту.

9. Перетворення з String в wchar_t. Приклад використання керованого покажчика (^)

При даному перетворенні використовується метод

pin_ptr <const wchar_t> PtrToStringChars(dest)

де вхідний параметр dest – рядок типу String. Метод повертає покажчик на перший символ рядка типу String. Цей покажчик можна передавати в функцію wcscpy_s().

Функція wcscpy_s() отримує два параметри:

1. Параметр типу wchar_t* (або wchar_t[]). Цей параметр є результуючим рядком типу wchar_t[].

2. Параметр типу pin_ptr <type>. Зарезервоване слово pin_ptr означає, що покажчик потрібно закріпити. Такий покажчик називається “покажчиком закріплення“. У нашому випадку це є покажчик на перший символ рядка типу String. “Покажчик закріплення” – це внутрішній покажчик, який не допускає щоб об’єкт перемістився за межі виділеного йому об’єму пам’яті. Слово <type> нашому випадку замінюється на <const wchar_t>.

Щоб використати методи PtrToStringChars() та wcscpy_s() потрібно підключити модулі <vcclr.h> та <cstring>.

Приклад. Перетворення рядка src типу String в рядок dest типу wchar_t.

#include <cstring>
#include <vcclr.h>

...

// перетворення з String в wchar_t
String ^src = gcnew String("This is a text"); // вихідний рядок src
wchar_t dest[50]; // результуючий рядок
pin_ptr <const wchar_t> pdest = PtrToStringChars(src); // отримати покажчик на результат
wcscpy_s(dest, pdest); // dest = "This is a text"

Метод PtrToStringChars() отримує вхідним параметром рядок типу String.


Зв’язані теми