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

时间:2014-09-02 08:05:38

标签: 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*)&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++;
}

在阅读this answer之后,我在互联网上做了一些研究并找到this article,所以我尝试使用本文中读到的这段代码修改上面的代码(见下文)。但是,这种变化并没有解决问题。

for (LPTSTR pszz = pszzStart; *pszz; pszz += lstrlen(pszz) + 1) {
 ... do something with pszz ...
}

正如在this answer中假设的那样,代码似乎需要双空终止的字符串数组。因此,我想知道如何检查inputStr字符串的内容,以检查它是否实际上只包含一个空终止符字符。

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

5 个答案:

答案 0 :(得分:2)

好了,既然你已经包含了剩下的代码,那么很明显它确实意味着解析一组连续的字符串。问题是你正在混合窄字符串和宽字符串类型。您需要做的就是更改变量定义(并删除强制转换):

char *arrayStr[STR_COUNT];
char *inputStr;
char *str;

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

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

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

    i++;
}

具体来说,问题出现在这一行:

while( *str != '\0' )

由于你没有将str强制转换为char *,因此比较正在寻找一个广泛而不是一个狭窄的区域。

答案 1 :(得分:1)

str = str + strlen(str) + 1;

你走出界限,改为

str = str + 1;

或简单地说:

str++;

答案 2 :(得分:1)

当然,你不一致地使用TSTRstrlen,后者假设TCHAR = char

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

你的算术是一个,但你知道在分配缓冲区时你必须在字符串的长度上添加一个。

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

有时你可能会因为阅读它而逃脱,如果有额外的填充,但它是未定义的行为,这里你有一个段错误。

答案 3 :(得分:1)

这对我来说就像是需要双空终止字符串数组的代码。我怀疑你传递一个空终止字符串。

所以你正在使用这样的东西:

const char* inputStr = "blah";

但代码需要两个null终止符。如:

const char* inputStr = "blah\0";

或者可能是包含多个字符串的输入值:

const char* inputStr = "foo\0bar\0";

请注意,这两个最终的两个字符串确实是双空终止的。虽然在字符串末尾只显式写入一个空终止符,但编译器会隐式添加另一个。


你的问题编辑引发了一个新的扳手?演员

strlen((char*)str)

非常可疑。如果你需要施放那么施法必定是错误的。人们想知道LPTSTR为你扩展的内容。据推测,它扩展到wchar_t*,因为您添加了强制转换以使代码编译。如果是这样,那么演员就没有好处。你对编译器撒谎(str不是char*)并且对编译器撒谎永远不会结束。

答案 4 :(得分:0)

Alter的答案已经给出了分段错误的原因。但是,我想补充一点,解析C风格字符串的常用方式更优雅,更简洁

while (char ch = *str++)
{
    // other instructions
    // ...
}

ch的范围仅在循环体内。

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