前缀的“sz”部分很重要,因为Windows世界中的某些字符串(特别是在谈论DDK时)不是零终止的。reading this in STR,LPSTR section
谁能告诉我那些非空终止的字符串是什么?
答案 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函数只接受字符串指针(SetWindowText
,CreateFile
),字符串必须以空字符终止。其他函数(ExtTextOut
,WriteConsole
)取指针和某种形式的长度(通常是char
s,TCHAR
或wchar_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
字符串(或将其复制到临时缓冲区)。此函数允许使用不带空终止要求的字符串部分。