调用strcpy后,第二个char数组变空

时间:2018-03-12 09:12:19

标签: c++ strcpy strncpy

这是我程序中的函数原型:
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;

输出: enter image description here

但是在我编写的简单测试程序中,我发现它不会被清空:

#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;
}

输出: enter image description here

我的计划出了什么问题?

2 个答案:

答案 0 :(得分:5)

char tmp[] ="";

在这里,您将创建一个具有足够空间来容纳字符串文字的字符数组,包括终止nul。由于字符串文字为空,因此该字符数组只包含一个字符。

如果您写的不止于此(并且您这样做),则进入未定义行为的领域。基本上你是把你的字符串倾倒在堆栈中的随机位置;可以预见,这并不能很好地结束。

你需要确保你的角色阵列有足够的空间来做你想做的事。

此外,您的程序逻辑看起来完全破碎。我不知道该代码应该如何执行函数名称所暗示的那样。

答案 1 :(得分:3)

char tmp[] ="";

这声明了一个char的本地数组(它只包含'\x0'终止符。)

将多个字符复制到此数组会导致未定义的行为:在这种情况下,它会破坏存储局部变量的堆栈帧。

如果您想要指针,请声明char *tmp。更好的是,只需使用std::string即可。