strcpy ...想用strcpy_mine替换strncpy和null终止

tim*_*B33 6 c c++ strcpy

线索在标题中,但基本上我继承了一些有800多个strcpy实例的代码.我想编写一个新函数,然后用strcpy_mine替换strcpy.

所以我想弄清楚strcpy_mine将包含哪些参数列表.

我试过了:

void strcpy_mine( char* pTarget, const char* const pCopyMe )
{
  const unsigned int lenAlwaysFour = sizeof(pCopyMe ); //:(
  strncpy( pTarget, pCopyMe, lenAlwaysFour );

  //add extra terminator in case of overrun
  pTarget[lenAlwaysFour] = 0;
}
Run Code Online (Sandbox Code Playgroud)

但sizeof总是4 pCopyMe是一个指针

我不想做的就是更换

strcpy (buf, pCopyMe);
Run Code Online (Sandbox Code Playgroud)

strncpy (buf, pCopyMe, sizeof(pCopyMe)); buf[sizeof(pCopyMe)] = 0;
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?(strcpy_l不可用)

干杯

Dou*_*der 11

sizeof()返回类型的大小 - 在这种情况下const char* const,在32位计算机上将为4.

我想你认为你想要strlen().但这不是使用strncpy函数的正确方法.你需要输出缓冲区的大小为strncpy.

要解决此问题,您需要检查每个调用站点的代码,并计算输出缓冲区的大小,并将其作为参数传递给strcpy_mine.如果strcpy(或strcpy_mine)的调用站点不知道输出缓冲区的大小,则需要在代码中向后搜索分配缓冲区的位置,并将大小一直传递给strcpy站点.

基本上你不能写一个替代strcpy取代相同的参数,并希望避免首先产生strncpy的问题(​​以及更好的替代).您可以创建一个与strncpy具有相同参数的函数,但确保结果以null结尾 - 查看OpenBSD的strlcpy()函数的实现.但第一步必须是更改调用站点以传递输出缓冲区大小的知识.


Sum*_*uma 4

根据调用站点的外观,大多数情况通常可以通过简单的模板来处理:

#include <string.h>

template <int bufferSize>
void strcpy_mine( char (&pTarget)[bufferSize], const char* const pCopyMe )
{
  strncpy( pTarget, pCopyMe, bufferSize-1 );

  //add extra terminator in case of overrun
  pTarget[bufferSize-1] = 0;
}

int main()
{
  char buf[128];
  strcpy_mine(buf,"Testing");
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果您使用的是 Microsoft Visual Studio 2005 或更高版本,请参阅Microsoft 实施的安全模板重载。