什么是非null终止字符串?

时间:2018-06-05 12:58:56

标签: c winapi

前缀的“sz”部分很重要,因为Windows世界中的某些字符串(特别是在谈论DDK时)不是零终止的。reading this in STR,LPSTR section

谁能告诉我那些非空终止的字符串是什么?

3 个答案:

答案 0 :(得分:2)

在计算机科学中,字符串a sequence of characters。序列有一定长度 - 其中有一些字符。要使用字符串,通常必须知道字符串的长度。

长度可以以各种方式指示。一种方法是使用sentinel value指示序列的结尾,{{3}}只是序列中未使用的选定值。对于字符串,通常使用零作为标记:字符串从其开始继续,直到找到零字符。使用sentinel时,sentinel值不会出现在字符串中,因为它标记了结尾。

指示长度的另一种方法是将其与字符串分开。例如,长度作为单独的参数传递给C memcmp例程。这允许memcmp比较内存中的任意字节序列,包括包含零字节的序列。

有时,长度被视为字符串数据结构的一部分。它可能位于字符串的第一个字节或前几个字节中。所以使用字符串的软件会通过读取第一个字节获得长度,之后的字节将包含字符串的字符。

与sentinel方法相关的另一种方法是使用分隔符。例如,我们通常在源代码,文本和shell命令中编写诸如"abc"之类的字符串。引号是分隔符,用于标记字符串的开头和结尾。各种方法用于允许分隔符本身成为字符串中的字符,例如使用其他特殊字符“引用”分隔符,如:"This is a quote mark: \"."

总之,非空终止字符串的概念是广泛和开放的:除了用空字符标记结尾之外,任何指示字符串长度的方法都是非空终止的字符串。

答案 1 :(得分:0)

在Windows内核编程中,最常用的字符串类型是UNICODE_STRING,这是非空终止的字符串类型:

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING

此数据结构的目的是有效地处理字符串 堆栈驱动程序。堆栈中的每个驱动程序都可以在“ MaximumLenth”范围内追加文本或修改字符串,而无需分配新的缓冲区。

例如,以下是存储在连续64个字节缓冲区中的典型unicode字符串:

address + 0 : 22 (Length) 
address + 4 : 48 (MaximumLength)
address + 8 : buffer + 16 (Buffer)
address + 16: "Hello World" (UTF16 string, may without null terminated)

标准的字符串操作函数不能在UNICODE_STRING上使用,而应该使用Rtl * UnicodeString()函数。

答案 2 :(得分:-1)

当我们可以使用非空终止字符串时,它会更容易回答。

某些API函数只接受字符串指针(SetWindowTextCreateFile),字符串必须以空字符终止。其他函数(ExtTextOutWriteConsole)取指针和某种形式的长度(通常是char s,TCHARwchar_t s的数量。不必以空字符结束。

// No termination NUL charcter bellow.
TCHAR hello[] = { 'H','E','L','L','O' };
ExtTextOut( hdc, 100, 100, 0, hello, 5, 0 );
TCHAR hello2[] = _T("HELLO WORLD!");
ExtTextOut( hdc, 100, 100, 0, hello2, 5, 0 );

在第二个ExtTextOut中,我们不必人为地剪切hello2字符串(或将其复制到临时缓冲区)。此函数允许使用不带空终止要求的字符串部分。