char *strncpy(char *dest,const char *src,size-t n);
时间: 2023-08-24 21:05:41 浏览: 206
`strncpy` 函数是 C 语言中用于将一个字符串复制到另一个字符串的函数。函数原型如下:
```c
char *strncpy(char *dest, const char *src, size_t n);
```
该函数的作用是将 `src` 字符串的最多前 `n` 个字符复制到 `dest` 字符串中,并返回 `dest` 字符串的指针。
参数说明:
- `dest`:目标字符串,复制后结果存放在此字符串中。
- `src`:源字符串,要被复制的字符串。
- `n`:要复制的最大字符数。
需要注意的是,如果 `src` 的长度不足 `n`,则 `dest` 字符串将被 `'\0'` 字符填充以达到总共 `n` 个字符的长度。
使用示例:
```c
#include <stdio.h>
#include <string.h>
int main() {
char dest[10];
const char src[] = "Hello, world!";
size_t n = 5;
strncpy(dest, src, n);
dest[n] = '\0'; // 手动添加终止符,以确保结果字符串终止
printf("%s\n", dest); // 输出:Hello
return 0;
}
```
在上面的示例中,我们将 `src` 字符串的最多前 5 个字符复制到了 `dest` 字符串中,并手动添加了终止符(`'\0'`)。然后打印出了最终的结果。
相关问题
实现以下函数 char *my_strcpy(char *dest,char const *src); char *my_strncpy(char *dest,char const *src,int len); char *my_strcat(char *dest,char const *src); char *my_strncat(char *dest,char const *src,int len); int my_strcmp(char *str1,char const *str2); int my_strncmp(char *srr1,char const *str2,int len);
下面是实现上述函数的示例代码:
```c
#include <stdio.h>
char *my_strcpy(char *dest, char const *src) {
char *temp = dest;
while ((*dest++ = *src++))
;
return temp;
}
char *my_strncpy(char *dest, char const *src, int len) {
char *temp = dest;
while (len > 0 && (*dest++ = *src++)) {
len--;
}
if (len > 0) {
*dest = '\0';
}
return temp;
}
char *my_strcat(char *dest, char const *src) {
char *temp = dest;
while (*dest) {
dest++;
}
while ((*dest++ = *src++))
;
return temp;
}
char *my_strncat(char *dest, char const *src, int len) {
char *temp = dest;
while (*dest) {
dest++;
}
while (len > 0 && (*dest++ = *src++)) {
len--;
}
if (len > 0) {
*dest = '\0';
}
return temp;
}
int my_strcmp(char *str1, char const *str2) {
while (*str1 && (*str1 == *str2)) {
str1++;
str2++;
}
return *(unsigned char *)str1 - *(unsigned char *)str2;
}
int my_strncmp(char *str1, char const *str2, int len) {
while (len > 0 && *str1 && (*str1 == *str2)) {
str1++;
str2++;
len--;
}
if (len == 0) {
return 0;
}
return *(unsigned char *)str1 - *(unsigned char *)str2;
}
int main() {
char dest[100] = "Hello";
char src[] = "World";
printf("strcpy: %s\n", my_strcpy(dest, src));
char dest2[100] = "Hello";
printf("strncpy: %s\n", my_strncpy(dest2, src, 3));
char dest3[100] = "Hello";
printf("strcat: %s\n", my_strcat(dest3, src));
char dest4[100] = "Hello";
printf("strncat: %s\n", my_strncat(dest4, src, 3));
char str1[] = "abc";
char str2[] = "abc";
printf("strcmp: %d\n", my_strcmp(str1, str2));
char str3[] = "abcd";
char str4[] = "abce";
printf("strncmp: %d\n", my_strncmp(str3, str4, 3));
return 0;
}
```
上述代码演示了如何实现 `my_strcpy`、 `my_strncpy`、 `my_strcat`、 `my_strncat`、 `my_strcmp` 和 `my_strncmp` 函数。你可以根据需要调用这些函数,并根据具体的参数和返回值进行相应的操作。
下面的代码修改一下 需要支持https双向认证int https_post(const char *cert_path, const char *url, const char *body, char *response) { int sockfd, len; struct sockaddr_in dest; struct hostent *host; SSL_CTX *ctx; SSL ssl; char request[MAX_BUF_SIZE], buf[MAX_BUF_SIZE]; // 初始化OpenSSL库 SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); // 解析主机名 //printf("66666666 %s\n", url); char hostname[2560]; getHostFromURL(url, hostname); host = gethostbyname(hostname); if (host == NULL) { perror("gethostbyname"); return -1; } // 创建套接字 sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket"); return -1; } // 设置目标地址 bzero(&dest, sizeof(dest)); dest.sin_family = AF_INET; dest.sin_port = htons(443); dest.sin_addr.s_addr = (long)host->h_addr; // 连接服务器 if (connect(sockfd, (struct sockaddr)&dest, sizeof(dest)) != 0) { perror("connect"); return -1; } ctx = SSL_CTX_new(TLS_method()); // 设置支持的协议版本为 TLSv1.2 SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION); if (ctx == NULL) { perror("SSL_CTX_new"); return -1; } // 加载证书 if (SSL_CTX_load_verify_locations(ctx, cert_path, NULL) != 1) { perror("SSL_CTX_load_verify_locations"); return -1; } // 创建SSL ssl = SSL_new(ctx); if (ssl == NULL) { perror("SSL_new"); return -1; } // 将套接字绑定到SSL SSL_set_fd(ssl, sockfd); // SSL握手 if (SSL_connect(ssl) == -1) { perror("SSL_connect"); return -1; } // 构造HTTP请求 char *escaped_url = urlencode(url); sprintf(request, "POST / HTTP/1.1\r\n" "Host: %s\r\n" "Content-Type: application/json\r\n" "Content-Length: %d\r\n" "\r\n" "%s", escaped_url, strlen(body), body); // 发送HTTP请求 SSL_write(ssl, request, strlen(request)); // 接收HTTP响应 len = SSL_read(ssl, buf, MAX_BUF_SIZE); printf("response %s\n", buf); // 关闭SSL和套接字 SSL_free(ssl); close(sockfd); // 处理响应 strncpy(response, buf, len); printf("Child process created with PID %d\n", 60909); response[len] = '\0'; printf("Child process created with PID %d\n", 70909); // 清理OpenSSL库 SSL_CTX_free(ctx); EVP_cleanup(); printf("Child process created with PID %d\n", 909); free(escaped_url); return 0; }
以下是修改后的代码,支持https双向认证:
```
int https_post(const char *cert_path, const char *key_path, const char *url, const char *body, char *response) {
int sockfd, len;
struct sockaddr_in dest;
struct hostent *host;
SSL_CTX *ctx;
SSL *ssl;
char request[MAX_BUF_SIZE], buf[MAX_BUF_SIZE];
// 初始化OpenSSL库
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
// 解析主机名
char hostname[2560];
getHostFromURL(url, hostname);
host = gethostbyname(hostname);
if (host == NULL) {
perror("gethostbyname");
return -1;
}
// 创建套接字
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket");
return -1;
}
// 设置目标地址
bzero(&dest, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(443);
dest.sin_addr.s_addr = *(long*)host->h_addr;
// 连接服务器
if (connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) != 0) {
perror("connect");
return -1;
}
ctx = SSL_CTX_new(TLS_method());
if (ctx == NULL) {
perror("SSL_CTX_new");
return -1;
}
// 设置支持的协议版本为 TLSv1.2
SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
// 加载 CA 证书
if (SSL_CTX_load_verify_locations(ctx, cert_path, NULL) != 1) {
perror("SSL_CTX_load_verify_locations");
return -1;
}
// 加载客户端证书和私钥
if (SSL_CTX_use_certificate_file(ctx, cert_path, SSL_FILETYPE_PEM) <= 0) {
perror("SSL_CTX_use_certificate_file");
return -1;
}
if (SSL_CTX_use_PrivateKey_file(ctx, key_path, SSL_FILETYPE_PEM) <= 0) {
perror("SSL_CTX_use_PrivateKey_file");
return -1;
}
if (!SSL_CTX_check_private_key(ctx)) {
perror("SSL_CTX_check_private_key");
return -1;
}
// 创建 SSL
ssl = SSL_new(ctx);
if (ssl == NULL) {
perror("SSL_new");
return -1;
}
// 将套接字绑定到SSL
SSL_set_fd(ssl, sockfd);
// SSL握手
if (SSL_connect(ssl) == -1) {
perror("SSL_connect");
return -1;
}
// 构造HTTP请求
char *escaped_url = urlencode(url);
sprintf(request, "POST / HTTP/1.1\r\n"
"Host: %s\r\n"
"Content-Type: application/json\r\n"
"Content-Length: %d\r\n"
"\r\n"
"%s", escaped_url, strlen(body), body);
// 发送HTTP请求
SSL_write(ssl, request, strlen(request));
// 接收HTTP响应
len = SSL_read(ssl, buf, MAX_BUF_SIZE);
// 关闭SSL和套接字
SSL_shutdown(ssl);
SSL_free(ssl);
close(sockfd);
// 处理响应
strncpy(response, buf, len);
response[len] = '\0';
// 清理OpenSSL库
SSL_CTX_free(ctx);
EVP_cleanup();
free(escaped_url);
return 0;
}
```
您需要将证书路径和私钥路径作为参数传入,以支持双向认证。其中,cert_path 是 CA 证书路径,key_path 是客户端证书和私钥路径。
阅读全文