C++ 如何检查LPTSTR字符串的内容?

C++ 如何检查LPTSTR字符串的内容?,c++,c,windows,qt,C++,C,Windows,Qt,我试图理解为什么在执行这段代码时会出现分段错误(SIGSEGV)。当测试while指令中指定的条件时,会发生此错误,但它不会在第一次迭代时发生,而是在第二次迭代时发生 LPTSTR arrayStr[STR_COUNT]; LPTSTR inputStr; LPTSTR str; // calls a function from external library // in order to set the inputStr string set_input_str(param1, (char

我试图理解为什么在执行这段代码时会出现分段错误(SIGSEGV)。当测试
while
指令中指定的条件时,会发生此错误,但它不会在第一次迭代时发生,而是在第二次迭代时发生

LPTSTR arrayStr[STR_COUNT];
LPTSTR inputStr;
LPTSTR str;

// calls a function from external library
// in order to set the inputStr string
set_input_str(param1, (char*)&inputStr, param3);

str = inputStr;
while( *str != '\0' )
{
    if( debug )
        printf("String[%d]: %s\n", i, (char*)str);

    arrayStr[i] = str;
    str = str + strlen((char*)str) + 1;

    i++;
}
str = str + strlen(str) + 1;
阅读之后,我在互联网上做了一些研究并发现,因此我尝试修改上述代码,使用本文中阅读的这段代码(见下文)。然而,这一变化并没有解决问题

for (LPTSTR pszz = pszzStart; *pszz; pszz += lstrlen(pszz) + 1) {
 ... do something with pszz ...
}
如中所假设的,代码似乎需要字符串的双空终止数组。因此,我想知道如何检查
inputStr
字符串的内容,以便检查它是否实际上只包含一个空终止符字符

注意:
printf
指令打印的字符串中的字符数是第一次迭代时
lstrlen(str)
函数调用返回的值的两倍

LPTSTR arrayStr[STR_COUNT];
LPTSTR inputStr;
LPTSTR str;

// calls a function from external library
// in order to set the inputStr string
set_input_str(param1, (char*)&inputStr, param3);

str = inputStr;
while( *str != '\0' )
{
    if( debug )
        printf("String[%d]: %s\n", i, (char*)str);

    arrayStr[i] = str;
    str = str + strlen((char*)str) + 1;

    i++;
}
str = str + strlen(str) + 1;
你出界了,换成

str = str + 1;
或者简单地说:

str++;

Alter的回答已经给出了分段错误的原因。但是,我想补充一点,解析C风格字符串的通常风格更优雅,也不太冗长

while (char ch = *str++)
{
    // other instructions
    // ...
}
ch
的范围仅在循环体中


旁白:可以将问题标记为
C
C++
,但不是两者都是,它们是不同的语言。

当然,您使用的是
TSTR
strlen
,后者假设
TCHAR=char

在任何情况下,
strlen
都会返回字符串的长度,即它包含的字符数,不包括nul字符

您的算术结果是1,但您知道在分配缓冲区时必须将1添加到字符串长度

然而,在这里,您从位置0开始,添加长度,这意味着您处于位置
len
,这是字符串的长度。现在字符串从offset
0
运行到offset
len-1
,offset
len
保存空字符。偏移量
len+1
超出范围


有时,如果有额外的填充,您可能不必阅读它,但这是未定义的行为,这里有一个segfault。

在我看来,这就像是需要以双null结尾的字符串数组的代码。我怀疑您正在传递一个以null结尾的字符串

因此,您使用的是如下内容:

const char* inputStr = "blah";
但是代码需要两个空终止符。例如:

const char* inputStr = "blah\0";
或者可能是具有多个字符串的输入值:

const char* inputStr = "foo\0bar\0";
请注意,最后两个字符串实际上是以双null结尾的。虽然只有一个空终止符显式地写在字符串的末尾,但编译器会隐式地添加另一个空终止符


你的问题编辑会给你带来新的麻烦吗?演员阵容

strlen((char*)str)

这是非常可疑的。如果你需要施法,那么施法肯定是错误的。人们想知道
LPTSTR
为您扩展了什么。大概它会扩展到
wchar\u t*
,因为您添加了强制转换以使代码能够编译。如果是这样,那么演员阵容就没有什么好处了。你在对编译器撒谎(
str
不是
char*
),对编译器撒谎永远不会有好结果。

好的,既然你已经包含了代码的其余部分,那么很明显,它确实是用来解析一组连续字符串的。问题是你混合了窄字符串和宽字符串类型。要修复它,您只需更改变量定义(并删除强制转换):

具体而言,问题发生在这一行:

while( *str != '\0' )

由于您没有将
str
转换为
char*
,因此比较是寻找一个宽的nul,而不是一个窄的nul。

您认为
str=str+strlen(str)+1是吗?好的,最后的
+1
超出了范围,但我不知道这段代码的目标是什么。编写循环时可能需要一组连续的字符串,而不是一个字符串。我认为如果您让我们看到注释掉的其他指令,可能会有所帮助。这可能会证实(或以其他方式)我和@Harry的预感。@DavidHeffernan:其他指令不会改变
str
。问题是我不知道这段代码的目标是什么:似乎在每次迭代中,我们都希望移到字符串的末尾,但我不明白原因…它叫指针算法,看看C-FAQ的例子,最后你有一个类似的strcpy实现的例子。@Alter实际上,情况根本不是这样的,如何在
LPTSTR
中单独打印每个字符?如何在LPTSTR的末尾添加额外的空终止符?如何打印每个字符?这听起来是一个完全不同的问题。至于下一条评论,我展示了如何在答案中使用双空终止。+1我的猜测是,原始代码没有充分的理由使用TCHAR,为ANSI编译,并使用strlen等。然后询问者出现,用Unicode编译代码,发现它无法编译,丢弃错误,并为欺骗编译器付出代价。