这是我程序中的函数原型:
void FindRepStr(char str[], const char findStr[], const char replaceStr[]);
它在findStr[]
中找到str[]
并将其替换为replaceStr[]
。
这是我的代码:
void FindRepStr(char str[], const char findStr[], const char replaceStr[])
{
char *s = nullptr;
s = strstr(str,findStr); //s points to the first-time appear in str
char tmp[] ="";
//length equal
if(strlen(findStr)==strlen(replaceStr))
{
for(int i=0;i<strlen(findStr);i++)
{
if(replaceStr[i]=='\0' || s[i] =='\0')
break;
else
s[i] = replaceStr[i];
}
cout<<str<<endl;
}
else
{
//find shorter than replace
if(strlen(findStr)<strlen(replaceStr))
{
//!!!problem here!!!
strncpy(tmp,s,strlen(s)+1); // store the left part
for(int i=0;i<=strlen(replaceStr);i++)
{
if(replaceStr[i]=='\0') //if end of replace
{
s[i]='\0'; //make s(str) end here
break;
}
else
s[i] = replaceStr[i]; //if not end, give the value
}
}
//finder longer than replace
else
{
//...not finished yet
}
}
}
我还没有完成这个,但是在strncpy之后,我打印了s和tmp进行测试,我发现tmp被正确复制了,但s打印出来是空的:
cout<<"s before strncpy:"<<s<<endl;
strncpy(tmp,s,strlen(s)+1);
cout<<"tmp after strncpy:"<<tmp<<endl;
cout<<"s after strncpy:"<<s<<endl;
但是在我编写的简单测试程序中,我发现它不会被清空:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char a[]="abc";
char b[]="defgh";
cout<<"a before:"<<a<<endl;
cout<<"b before:"<<b<<endl;
strncpy(a,b,strlen(b)+1);
cout<<"a after:"<<a<<endl;
cout<<"b after:"<<b<<endl;
return 0;
}
我的计划出了什么问题?
答案 0 :(得分:5)
char tmp[] ="";
在这里,您将创建一个具有足够空间来容纳字符串文字的字符数组,包括终止nul。由于字符串文字为空,因此该字符数组只包含一个字符。
如果您写的不止于此(并且您这样做),则进入未定义行为的领域。基本上你是把你的字符串倾倒在堆栈中的随机位置;可以预见,这并不能很好地结束。
你需要确保你的角色阵列有足够的空间来做你想做的事。
此外,您的程序逻辑看起来完全破碎。我不知道该代码应该如何执行函数名称所暗示的那样。
答案 1 :(得分:3)
char tmp[] ="";
这声明了一个char的本地数组(它只包含'\x0'
终止符。)
将多个字符复制到此数组会导致未定义的行为:在这种情况下,它会破坏存储局部变量的堆栈帧。
如果您想要指针,请声明char *tmp
。更好的是,只需使用std::string
即可。