snprintf的返回值代表字节数 != 实际写入字节数

本文通过实例深入解析了snprintf函数的行为,展示了即使目标缓冲区长度不足,该函数仍能正确返回所需字符串长度的特性。文章揭示了在C语言中处理字符串时可能遇到的缓冲区溢出问题,并提供了代码示例。
#include <stdio.h>
int main(void)
{
    char buf[4];
    int cnt=0;

    cnt = snprintf(buf, sizeof(buf), "(%x)", 0xF123);

    printf("buf = %s\n", buf);
    printf("cnt = %d\n", cnt);
    return 0;
}

上述代码的运行结果,snprintf()返回值 cnt = 6大于buf的实际字节数:

buf = (f1
cnt = 6
按 <RETURN> 来关闭窗口...

继续测试

修改buf数组字节数(例如改为2):

#include <stdio.h>
int main(void)
{
    char buf[2];
    int cnt=0;

    cnt = snprintf(buf, sizeof(buf), "(%x)", 0xF123);

    printf("buf = %s\n", buf);
    printf("cnt = %d\n", cnt);
    return 0;
}

char型数组char buf[4];无论分配多少个字节, 运行结果cnt都等于6!

buf = (
cnt = 6
按 <RETURN> 来关闭窗口...
int generate_temp_cert_mbedtls(const char* mac_str, const char* key_path, const char* cert_path) { int ret; mbedtls_pk_context key; mbedtls_x509write_cert crt; mbedtls_mpi serial; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; unsigned char output_buf[4096]; FILE *f; // 初始化 mbedtls_pk_init(&key); mbedtls_x509write_crt_init(&crt); mbedtls_mpi_init(&serial); mbedtls_entropy_init(&entropy); mbedtls_ctr_drbg_init(&ctr_drbg); // 初始化随机数生成器 ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char*)"cert_gen", 8); if (ret != 0) { goto cleanup; } // 生成ECC密钥对 (secp256r1) ret = mbedtls_pk_setup(&key, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)); if (ret != 0) { goto cleanup; } ret = mbedtls_ecp_gen_key(MBEDTLS_ECP_DP_SECP256R1, mbedtls_pk_ec(key), mbedtls_ctr_drbg_random, &ctr_drbg); if (ret != 0) { goto cleanup; } // 保存私钥到文件 ret = mbedtls_pk_write_key_pem(&key, output_buf, sizeof(output_buf)); if (ret != 0) { goto cleanup; } f = fopen(key_path, "wb"); if (f == NULL) { goto cleanup; } fwrite(output_buf, 1, strlen((char*)output_buf), f); fclose(f); // 设置证书参数 mbedtls_x509write_crt_set_version(&crt, MBEDTLS_X509_CRT_VERSION_3); mbedtls_x509write_crt_set_md_alg(&crt, MBEDTLS_MD_SHA256); // 设置序列号 ret = mbedtls_mpi_read_string(&serial, 10, "1"); if (ret != 0) { goto cleanup; } ret = mbedtls_x509write_crt_set_serial(&crt, &serial); if (ret != 0) { goto cleanup; } // 设置Subject和Issuer (自签名) char subject[256]; snprintf(subject, sizeof(subject), "CN=%s,OU=NOC", mac_str); ret = mbedtls_x509write_crt_set_subject_name(&crt, subject); if (ret != 0) { goto cleanup; } ret = mbedtls_x509write_crt_set_issuer_name(&crt, subject); if (ret != 0) { goto cleanup; } // 设置有效期 (10年) ret = mbedtls_x509write_crt_set_validity(&crt, "20240101000000", "20341231235959"); if (ret != 0) { goto cleanup; } // 设置公钥 mbedtls_x509write_crt_set_subject_key(&crt, &key); mbedtls_x509write_crt_set_issuer_key(&crt, &key); // 添加扩展字段 // Basic Constraints: CA:FALSE ret = mbedtls_x509write_crt_set_basic_constraints(&crt, 0, -1); if (ret != 0) { goto cleanup; } // Key Usage: Digital Signature ret = mbedtls_x509write_crt_set_key_usage(&crt, MBEDTLS_X509_KU_DIGITAL_SIGNATURE); if (ret != 0) { goto cleanup; } // Subject Key Identifier ret = mbedtls_x509write_crt_set_subject_key_identifier(&crt); if (ret != 0) { goto cleanup; } // Authority Key Identifier ret = mbedtls_x509write_crt_set_authority_key_identifier(&crt); if (ret != 0) { goto cleanup; } // 生成证书 (PEM格式) memset(output_buf, 0, sizeof(output_buf)); ret = mbedtls_x509write_crt_pem(&crt, output_buf, sizeof(output_buf), mbedtls_ctr_drbg_random, &ctr_drbg); if (ret != 0) { goto cleanup; } // 保存证书到文件 f = fopen(cert_path, "wb"); if (f == NULL) { goto cleanup; } fwrite(output_buf, 1, strlen((char*)output_buf), f); fclose(f); ret = 0; cleanup: mbedtls_pk_free(&key); mbedtls_x509write_crt_free(&crt); mbedtls_mpi_free(&serial); mbedtls_ctr_drbg_free(&ctr_drbg); mbedtls_entropy_free(&entropy); return ret; }这个函数是为了生成一个自签证书和私钥,有什么问题吗
10-10
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值