如何使用strncpy_s()函数实现strncpy()功能? [英] How to achieve strncpy() functionality with strncpy_s() function?

查看:320
本文介绍了如何使用strncpy_s()函数实现strncpy()功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在某些情况下,我确实需要 strncpy()功能-例如,我在预定义的接口中有一个函数,该函数传递了缓冲区的地址和缓冲区的大小:

  HRESULT someFunction(char * buffer,size_t length); 

据记载,我可以在其中复制一个以空值结尾的字符串,长度不超过 length -如果长度恰好是 length ,则我不对字符串进行空终止,并且调用方知道字符串结束以空字符或长度 length 为准,以先发生的情况为准。



我当然会用 strncpy()为此

  HRESULT someFunction(char * buffer,size_t长度)
{
const char * toCopy = ...
size_t actualLength = strlen(toCopy);
if(actualLength> length){
return E_UNEXPECTED; //不适合,无法执行任何合理的操作
}
strncpy(buffer,toCopy,length);
返回S_OK;
}

现在我有了这段代码,需要将其从Visual C ++ 7迁移到Visual C ++9。我对其进行了编译,并看到警告, strncpy()是不安全的,我应该改用 strncpy_s()



strncpy_s() code>旨在始终以空值终止缓冲区,因此在上述情况下我不能将其用作直接替换。我必须在长度超过-1 (而不是 length <的字符串)上返回 E_UNEXPECTED / code>),否则一旦字符串的长度小于或等于$code $ c,就会启动无效的参数错误处理程序,否则程序将运行未定义的行为。 / p>

到目前为止,我应用的解决方案是只定义 _CRT_SECURE_NO_WARNINGS 并使编译器关闭。



有什么方法可以使用 strncpy_s()实际替换 strncpy()

解决方案

尝试使用 str * cpy *()具有固定目标缓冲区的方案的功能是一种常见的误解。这里的问题是那些函数复制直到出现空字符或其他条件。在这种情况下,将使用以下代码:

  size_t actualLength = strlen(toCopy); 
if(actualLength> length){
return E_UNEXPECTED; //不适合,无法执行任何合理的操作
}

代码在进行复制之前就知道了实际的字符串长度。一旦知道了长度,就可以使用 memcpy()有意义,这种情况简单明了,而且副作用也更快,因为它允许复制多于

  HRESULT someFunction(char * buffer,size_t length)一次只输入一个字符,并且不检查每个字符是否为空终止符。 
{
const char * toCopy = ...
size_t actualLength = strlen(toCopy);
if(actualLength> length){
return E_UNEXPECTED; //不适合,不能做任何合理的事情
}
memcpy(buffer,toCopy,min(length,actualLength + 1));
返回S_OK;
}

所以解决方案是忘记两个 strncpy( ) strncpy_s()并改用 memcpy()


There're certain cases when I really need strncpy() funcitonalty - for example I have a function in a predefined interface that is passed an address of the buffer and the size of the buffer:

HRESULT someFunction( char* buffer, size_t length );

and it is documented that I can copy a null-terminated string there with length no more than length - if it is exactly of length length I don't null-terminate the string and the caller knows that the string ends at either a null character or at length length whichever happens first and it all works.

Of course I will use strncpy() for that

HRESULT someFunction( char* buffer, size_t length )
{
    const char* toCopy = ...
    size_t actualLength = strlen( toCopy );
    if( actualLength > length ) {
        return E_UNEXPECTED; // doesn't fit, can't do anything reasonable 
    }
    strncpy( buffer, toCopy, length );
    return S_OK;
}

Now I have this code and need to migrate it from Visual C++ 7 to Visual C++ 9. I compile it and see a warning that strncpy() is unsafe and I should instead use strncpy_s().

strncpy_s() is designed to always null-terminate the buffer, so I can't use it as a direct replacement in the above scenario. I'll have to return E_UNEXPECTED on strings longer than length - 1 (not length as previously) or it will just fire an invalid parameters error handler once a string is of length or longer or the program will run into undefined behavior.

The solution I applied so far is to just define a _CRT_SECURE_NO_WARNINGS and make the compiler shut up.

is there any way to use strncpy_s() as an actual replacement to strncpy()?

解决方案

Trying to use str*cpy*() functions for scenarios with a fixed destination buffer is a common misconception. The deal here is that those functions "copy until a null character or other condition occurs". In this scenario there's this code in place:

size_t actualLength = strlen( toCopy );
if( actualLength > length ) {
    return E_UNEXPECTED; // doesn't fit, can't do anything reasonable 
}

and so the code knows the actual string length before it proceeds to copying. And once length is known it only makes sense to use memcpy() which is straightforward and concise for such scenarios and as a side effect also faster since it is allowed to copy more than one character at a time and doesn't check each character for null terminator.

HRESULT someFunction( char* buffer, size_t length )
{
    const char* toCopy = ...
    size_t actualLength = strlen( toCopy );
    if( actualLength > length ) {
        return E_UNEXPECTED; // doesn't fit, can't do anything reasonable 
    }
    memcpy( buffer, toCopy, min( length, actualLength + 1 ) );
    return S_OK;
}

So the solution is to just forget both strncpy() and strncpy_s() and use memcpy() instead.

这篇关于如何使用strncpy_s()函数实现strncpy()功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆