有这样的结构。
struct Address {
int id;
int set;
char name[MAX_DATA];
char email[MAX_DATA];
};
设定地址的功能。
void Database_set(struct Connection *conn, int id, const char *name, const char *email) {
struct Address *addr = &conn->db->rows[id];
if(addr->set) die("Address already set");
addr->set = 1;
char *res = strncpy(addr->name, name, MAX_DATA);
if(!res) die("Name copy failed");
*res = strncpy(addr->email, email, MAX_DATA);
if(!res) die("Email copy failed");
}
但addr-> name的第一个字符在此行之后被破坏。
*res = strncpy(addr->email, email, MAX_DATA);
有什么想法吗?
答案 0 :(得分:6)
strncpy
在
char *res = strncpy(addr->name, name, MAX_DATA);
变量res
包含addr->name
(相当于&(addr->name[0])
)所以
*res = strncpy(addr->email, email, MAX_DATA);
运行它相当于
addr->name[0] = strncpy(addr->email, email, MAX_DATA);
这项任务破坏了addr->name
的第一个字符。正如Greg Hewgill所说,您无需检查甚至保存strncpy
的返回值。
答案 1 :(得分:3)
我认为strncpy()
功能不是你想要的。考虑一下这个电话:
strncpy(addr->name, name, MAX_DATA);
如果name
有MAX_DATA
个或更多字符,则会将name
中的字节复制到addr->name
,而不会 NUL - 终止目的地。您有两种常规选择:
使用
等代码手动NUL终止结果addr->name[MAX_DATA-1] = '\0';
但是,这很容易出错,因为每次都必须记住这样做。
使用诸如strlcpy()
之类的库函数(通常在BSD派生的系统上可用,但不是标准的),它总是NUL终止目的地,即使源不完全适合。