调用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 即可。