我遇到了一个奇怪的问题,当我在函数内部输出printf
时,split
代码正确返回,但当作为示例调用它时,split
代码将错误返回输出。
- 问题**:当我把它作为一个示例调用时,我如何得到正确的输出?(见下面的用法)
下面是代码:
typedef struct SplitText
{
int splitLen;
char* splitTxt[100];
char* subTxt(char* text, int index, int len)
{
char subTxt_[1000];
int count = 0;
for (int i = 0; i < 1000; i++)
subTxt_[i] = '\0';
for (int i = index; i < index + len; i++)
subTxt_[count++] = text[i];
return subTxt_;
}
void split(char* text, char sep)
{
char separator[3] = { '<', sep, '>' };
int textLen = strlen(text);
int splitIndex = 0;
int splitCount = 0;
for (int t = 0; t < textLen; t++)
{
if (text[t] == separator[0] && text[t + 1] == separator[1] && text[t + 2] == separator[2])
{
if (splitIndex != 0)
splitIndex += 3;
splitTxt[splitCount] = subTxt(text, splitIndex, t - splitIndex);
splitIndex = t;
//correct output
printf(splitTxt[splitCount]);
printf("\n");
splitCount++;
}
}
splitLen = splitCount;
}
}SplitText;
用途:
SplitText st;
st.split("testing<=>split<=>function<=>", '=');
for (int i = 0; i < st.splitLen; i++)
{
//incorrect output
printf(st.splitTxt[i]);
printf("\n");
}
printf("--------\n");
3条答案
按热度按时间rta7y2nd1#
这一点:
返回一个指向局部堆栈变量(或局部数组变量)的指针会导致类似这样的奇怪事情发生。
破坏返回指针内容的典型情况是,当调用另一个函数时,
subTxt_
占用的内存将被下一个调用函数的堆栈变量覆盖。更好:
然后确保调用
subTxt
的人记住返回指针上的delete []
。或者直接使用
std::string
并完成它(除非这是学术练习)。此外,这是未定义的行为:
当
t == textLen-1
时,则引用text[t+2]
和text[t+1]
是越界访问。请将其更改为:并在块内对
t
执行类似的修复。e1xvtsh32#
你可以创建一个splitstring函数来代替struct/class。
无论如何,你的代码看起来仍然很像“C”,因为它有固定大小的字符数组,这将限制可用性和稳定性(超出范围的数组错误)。
C中的字符串通常是std::string.类型,然后C使用string_view对该字符串进行查看(因此不会复制任何数据,但这也意味着string_view仅在其查看的字符串存在期间有效)。
如果不知道字符串中子字符串的数目,就不应该使用固定大小的数组,而应该使用std::vector(如果需要,可以在内部调整大小)
这就是split_string函数在当前C++中的样子,注意,与“C”风格的编程相比,代码也更好地显示了它正在做什么,“C”风格的编程显示了更多你正在做什么。
xkrw2x1b3#
看一下 std::string_view。你可以避免分配内存,它有一个内置的子字符串函数。当使用printf打印到控制台时要小心,因为“%s”会打印整个字符串。请参阅printf文档。