Всегда ли CString завершается нулем? - PullRequest
2 голосов
/ 18 февраля 2011

Из интерфейса CString явно не следует предполагать, что CString имеет нулевое окончание.Однако иногда кажется, что на самом деле в конце строки есть нулевой символ.Возможно ли в реализации Windows создать строку CString, которая не имеет нулевой символ, так что при чтении одного символа после конца строки будет выглядеть другой объект кучи?

Ответы [ 4 ]

1 голос
/ 28 сентября 2012

A CString больше похоже на строку Visual Basic или BSTR. Он может содержать встроенные двоичные нули в части данных CString. Однако при использовании различных операторов для преобразования между CString и стандартными строками с нулевым символом в конце типа C встроенный двоичный ноль обрабатывается как символ конца строки. Так что CString очень похоже на тип переменной BSTR.

Например, я поместил следующие исходные строки в проект MFC и запустил его в отладчике Visual Studio C ++.

CString myString (_T("this\000is a String."));  // myString will only contain "this" as a zero terminated string.

CString myJJ;
myJJ.Format (_T("this%cisaxxx"), 0);   // this creates a string with an embedded binary zero in it.
int iLen = myJJ.GetLength();      // this returns the length of the complete string, 11 characters
CString myRight = myJJ.Right(4);  // this returns the right most 4 characters, "axxx"
TCHAR  myTbuff[64];
_tcscpy (myTbuff, myJJ);    // this copies the string up to the embedded binary zero into myTbuff

Что касается перехода к следующему объекту кучи, я бы не зависел от этого. Это зависит от реализации CString того, как объект размещен в памяти и как он использует память. Может случиться так, что если вы создадите CString, буфер размером 64 символа будет выделен независимо от того, сколько символов вы в него поместите. CString предоставляет метод GetLength(), чтобы узнать, сколько символов содержится в CString, поэтому их следует использовать. Существуют также методы для получения и установки определенных позиций символов.

CString был разработан, чтобы позволить программисту мыслить в терминах строк, как в строках типов Visual Basic, вместо того, чтобы иметь дело со строками стиля C, которые на самом деле являются массивами символов со специальным концом символа конца строки, двоичный ноль.

Edit01 - Аргументы компилятора и влияние на CString

Компиляторы Visual Studio, предшествовавшие Visual Studio 2013, позволяли классу CString создавать либо 8-битные многобайтовые наборы символов, либо 16-битные строки символов UNICODE в зависимости от того, были ли определены _MBCS или _UNICODE при обработке исходного файла.

Причина, по которой я говорю до появления Visual Studio 2013, заключается в том, что, по-видимому, использование _MBCS устарело (см. Также Побочный эффект устаревания поддержки MBCS для MFC в VS 2013 ).

Корень этой гибкости - определение TCHAR, которое может быть либо char, если определено _MBCS, либо wchar_t, если определено _UNICODE. Это, в свою очередь, определяет, что происходит с макросом _T() или TEXT(), который преобразует строку в кавычках в массив типа char или массив типа wchar_t, либо предварительно ожидая, либо не L используется для обозначения текстовой строки wchar_t. Это также влияет на фактический тип LPCTSTR (указатель на строку const TCHAR) или LPTSTR (указатель на неконстантную строку TCHAR).

В Windows 95/98 / ME не было встроенной поддержки UNICODE в Windows API, как в Windows NT / 2000 / XP, поэтому было полезно выбрать UNICODE для Windows NT или MBCS для Windows 95. Другим вариантом в то время был Microsoft Layer для Unicode, который предоставлял интерфейс UNICODE для Windows API для Windows 95/98 / ME.

0 голосов
/ 28 сентября 2012

Да, строка CString всегда завершается нулем.

В документации говорится, что вы можете привести CString к LPCTSTR, а LPCTSTR является typedef для одного из:
__nullterminated CONST WCHAR *
__nullterminated CONST CHAR *
в зависимости от того, определен ли UNICODE или нет.

0 голосов
/ 28 сентября 2012

Приведение к LPCTSTR обеспечит строку с нулевым символом в конце, но нет гарантии, что строка завершится нулем до этого преобразования. Он может легко завершить строку внутри функции.

Источник CString предоставлен Microsoft, лучший способ убедиться в этом - посмотреть, как именно все реализовано. Конечно, это всегда может измениться в следующей версии - CString претерпел немало изменений за эти годы.

0 голосов
/ 18 февраля 2011

Посмотрите документацию MSDN здесь:

http://msdn.microsoft.com/es-es/library/awkwbzyc(v=vs.80).aspx

Исходя из этого, я бы предположил, что там есть нулевой терминатор, вам просто нужно выполнить кастинг, чтобы получить его.

...