调用strcpy后,第二个char数组变空
After calling strcpy, the second char array becomes empty
这是我程序中的函数原型:
void FindRepStr(char str[], const char findStr[], const char replaceStr[]);
它在str[]
中找到findStr[]
并替换为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]=='[=10=]' || s[i] =='[=10=]')
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]=='[=10=]') //if end of replace
{
s[i]='[=10=]'; //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;
}
输出:
我的程序出了什么问题?
char tmp[] ="";
此处您正在创建一个字符数组,其中 space 足以容纳字符串文字,包括终止 nul。由于字符串文字为空,因此此字符数组正好包含一个字符。
如果你写的不止这些(你确实写了),你就进入了未定义行为的领域。基本上你是在堆栈中随机放置你的字符串;不出所料,结局并不好。
你需要确保你的字符数组有足够的space来做你想做的事。
此外,您的程序逻辑看起来完全错误。我不明白该代码应该如何执行函数名称建议的操作。
char tmp[] ="";
这声明了一个一个字符的本地数组(它只包含 '\x0'
终止符)。
将多个字符复制到此数组中会导致未定义的行为:在这种情况下,它会破坏存储局部变量的堆栈帧。
如果你想要一个指针,声明char *tmp
。更好的是,只需使用 std::string
即可。
这是我程序中的函数原型:
void FindRepStr(char str[], const char findStr[], const char replaceStr[]);
它在str[]
中找到findStr[]
并替换为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]=='[=10=]' || s[i] =='[=10=]')
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]=='[=10=]') //if end of replace
{
s[i]='[=10=]'; //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;
}
输出:
我的程序出了什么问题?
char tmp[] ="";
此处您正在创建一个字符数组,其中 space 足以容纳字符串文字,包括终止 nul。由于字符串文字为空,因此此字符数组正好包含一个字符。
如果你写的不止这些(你确实写了),你就进入了未定义行为的领域。基本上你是在堆栈中随机放置你的字符串;不出所料,结局并不好。
你需要确保你的字符数组有足够的space来做你想做的事。
此外,您的程序逻辑看起来完全错误。我不明白该代码应该如何执行函数名称建议的操作。
char tmp[] ="";
这声明了一个一个字符的本地数组(它只包含 '\x0'
终止符)。
将多个字符复制到此数组中会导致未定义的行为:在这种情况下,它会破坏存储局部变量的堆栈帧。
如果你想要一个指针,声明char *tmp
。更好的是,只需使用 std::string
即可。