C++ 如何检查LPTSTR字符串的内容?
我试图理解为什么在执行这段代码时会出现分段错误(SIGSEGV)。当测试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
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
,这是字符串的长度。现在字符串从offset0
运行到offsetlen-1
,offsetlen
保存空字符。偏移量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编译代码,发现它无法编译,丢弃错误,并为欺骗编译器付出代价。