众所周知,strcpy复制字符串是不安全的。
在C标准中有一个叫strncpy的函数,它带了一个n很具迷惑性,其实它也不是安全的。
VC下可以使用strncpy_s。
想要一个通用的复制字符串的方式除了手写一个类似strncpy_s函数之外,还有什么方法呢?
下面:
C/C++ code
char str[10] = { 0 };
strncpy(str, "a long long string", sizeof(str) - 1);
还是下面:
C/C++ code
char str[10] = { 0 };
memcpy(str, "a long long string", sizeof(str) - 1);
或许没有机会对str初始化的时候(如参数)这样:
C/C++ code
void foo(char *str, len)
{
strncpy(str, "a long long string", len - 1);
str[len - 1] = 0;
}
不过这些方法都还是依赖于程序员自己。
若是不小心,又或是程序员不懂strncpy等函数的行为,可能就会有潜在的问题。
不知道大家是怎么安全的复制字符串的?
这里不讨论std::string,本人是能用std::string的时候就会使用,但是在某些地方是没办法使用std::string,如网络协议中传输一个字符串:
C/C++ code
struct SomeProtocol
{
char str[100];
// other here ...
};
--------------------------------------------------------------------------------
用得不好,都不安全~
回复:[向ALL提问]大家是怎么安全的复制字符串
--------------------------------------------------------------------------------
有时候用 memcpy函数,好像也有不安全的情况
--------------------------------------------------------------------------------
如果被迫使用字符串拷贝,我比较喜欢用memcpy,这个控制力更强些。
如果是VC,StringCchCopy也是一个不错的选择。
--------------------------------------------------------------------------------
我感觉有些东西是不可避免的 只要用的时候细心就行了
--------------------------------------------------------------------------------
用std:string最安全
--------------------------------------------------------------------------------
你想要的安全是什么标准呢?不越界,线程安全还是啥。如果仅仅是指针合法和不越界,还算简单。要线程安全,标准库的都不是线程安全的吧,自己得加锁互斥实现。
--------------------------------------------------------------------------------
想要安全的话,没有问题,自己重写一遍字符串拷贝函数,在函数内部将所有可能发生的错误都进行相应的判断和处理,只要你想得到,这个函数绝对安全。
但是相对的,效率就没了,工具而已,会用就安全,不会用或者瞎用就危险,就这么简单。
--------------------------------------------------------------------------------
C/C++ code
char to[LEN + 1];
snprintf(to, sizeof(to), "%s", from);
--------------------------------------------------------------------------------
你想要的安全是什么标准呢?不越界,线程安全还是啥。如果仅仅是指针合法和不越界,还算简单。要线程安全,标准库的都不是线程安全的吧,自己得加锁互斥实现。
首先,这里讨论的肯定不是线程安全问题。
想要安全的话,没有问题,自己重写一遍字符串拷贝函数,在函数内部将所有可能发生的错误都进行相应的判断和处理,只要你想得到,这个函数绝对安全。
但是相对的,效率就没了,工具而已,会用就安全,不会用或者瞎用就危险,就这么简单。
对于自己写这个问题,在团队中是很难让一个团队中的每个人都会去调用自己写的函数。
而如果仅仅是自己个人写程序的话,那没什么意义了。
至少本人自己写程序是基本上都用std::string的,就是在某些不得已的情况下需要上述方法来处理也是没问题的,自己明白怎么用好,那写不写一个函数来处理这个问题的意义就不重要了。
--------------------------------------------------------------------------------
std::string
--------------------------------------------------------------------------------
C/C++ code
char to[LEN + 1];
snprintf(to, sizeof(to), "%s", from);
这个是可以,但是snprintf是C99函数,无奈VC不支持C99,也就只能在gcc下用了。
VC有个_snprintf但是其表现行为和snprintf不一样,不会自动添加0。
跨平台无奈中。。。
--------------------------------------------------------------------------------
memeset()先初始化,再assert(),最后memcpy();
这三者结合起来,呵呵。
反正任何东西都有两面性,要看你怎么用,如果你想用得最安全,采用迭代子,一个一个地复制,但效率欠缺。
综上所术:it all depends on ourselves.
--------------------------------------------------------------------------------
带长度限制的应该相对安全些,也便于检查
--------------------------------------------------------------------------------
没什么不安全的,不过习惯在复制后把最后一个字符设置成'\0'
貌似我都是用
char str[10] = { 0 };
strncpy(str, "a long long string", sizeof(str) - 1)
回复:[向ALL提问]大家是怎么安全的复制字符串
--------------------------------------------------------------------------------
strncpy
memcpy
--------------------------------------------------------------------------------
没有绝对的安全,也没有绝对的不安全。
奉劝楼主不要把有限的生命浪费在无限的加密解密死循环中!
--------------------------------------------------------------------------------
没有绝对的安全,也没有绝对的不安全。
奉劝楼主不要把有限的生命浪费在无限的加密解密死循环中!
传说中的机器?
--------------------------------------------------------------------------------
库函数没有绝对的安全,在使用的时候需要程序员自己控制。
--------------------------------------------------------------------------------
string也不安全,会有堆分配失败问题。
--------------------------------------------------------------------------------
strncpy,一般都用这个。
--------------------------------------------------------------------------------
- 原生字符串分ascii、多字节、unicode共3种
- 显然字符串的宽度为一个字符单元。在前两种下面等于字节数,后一种下面等于字数(一个字等于两个字节)。
- 用memcpy类的内存拷贝函数拷贝字符串是一种很不负责任的做法。
- 学校里教c语言居然还只是用纯ascii来教,无语... 字符串得用TCHAR表示,相应的函数为_tcscpy、_tcsncpy等。字符串还可能只用wchar_t或只用char。
- 回到该问题:栈内只能申请到长度很有限且固定的字符串。而堆中申请的字符串可以很长却有内存分配失败的可能。不管是堆还是栈,面临的字符串安全问题有两个:一个是缓冲区溢出、一个是无零字符结尾。使用类可以自动化的正确处理字符串。但因为字符串的长度在处理中可能变化,因此当前大多数字符串类是在堆中放置字符串的。对堆分配失败的处理就成了另一个问题。
--------------------------------------------------------------------------------
评论