Указатели. Часть 4. Указатели и строки символов. Использование указателей при преобразовании (конвертировании) строк

Указатели. Часть 4. Указатели и строки символов. Использование указателей при преобразовании (конвертировании) строк

Данная тема основывается на следующих темах:


Содержание

  1. Как описать неуправляемый указатель (*) на строчный литерал? Примеры
  2. Как описать указатель на строку, который описан как массив символов? Пример
  3. Как с помощью неуправляемого указателя (*) получить значение i-го элемента строки символов? Пример
  4. Преобразование из char в String. Пример использования управляемого указателя (^)
  5. Преобразование из wchar_t в String. Пример использования управляемого указателя (^)
  6. Преобразование из string в System.String. Пример использования управляемого указателя (^)
  7. Преобразование из String в char. Пример использования управляемого указателя (^)
  8. Преобразование из char в wchar_t. Пример использования неуправляемого указателя (*)
  9. Преобразование из String в wchar_t. Пример изпользования управляемого указателя (^)

1. Как описать неуправляемый указатель (*) на строчный литерал? Примеры

Более подробно о литералах описывается здесь.

Строка символов представляет собой строчный литерал, который есть массивом символов типа char. Адрес первого символа строчного литерала есть начальным значением указателя. Указатель на первый элемент строчного литерала есть указателем на весь строчный литерал.

Пример. Указатель ps на строчный литерал. Попытка изменить символ в строчном литерале.

// указатель на строчный литерал
// способ 1
char * ps;
ps = "This is a text"; // присвоение указателю строки символов

// способ 2
char * ps2 = "This is a text - 2";

// доступ к символу строки с помощью указателя
//*ps2 = 't'; - ошибка, изменять строчный литерал через указатель нельзя

При попытке изменения значения символа строчного литерала возникает ошибка:

Attempted to read or write protected memory

 

2. Как описать указатель на строку, который описан как массив символов? Пример

Имя массива символов есть указателем-константой. Если строка описана как массив символов, тогда можно изменять символы строки с помощью указателя.

Пример 1. Указатель на массив символов. Доступ к символу строки, который описан как массив символов.

// указатель на массив символов
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 = "Hello world!";
char c;

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 описывается в статье «Базовые типы данных C++».

Пример. Преобразование из типа 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.


Связанные темы