You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何分步调用格式化函数替换字符串中的格式占位符?

分批替换格式字符串占位符的实现方案

标准C库中的sprintf/snprintf会一次性解析所有格式说明符,缺省参数会导致未定义行为,无法满足你分批替换占位符的需求。要实现逐个替换格式符并保留剩余占位符的功能,你需要自定义处理逻辑,以下是具体实现方案:

核心思路

遍历当前字符串,定位第一个未被替换的格式说明符(跳过转义的%%),将其替换为对应参数值后,拼接剩余未处理的格式字符串,最终更新目标缓冲区。

自定义实现代码

#include <stdio.h>
#include <string.h>
#include <stdarg.h>

// 分批替换格式字符串的函数
int sprintf_step(char *buf, size_t buf_size, const char *fmt, ...) {
    va_list args;
    va_start(args, fmt);

    // 找到第一个%字符
    char *percent = strchr(fmt, '%');
    if (!percent) {
        // 无剩余格式符,直接复制原字符串
        return snprintf(buf, buf_size, "%s", fmt);
    }

    // 处理转义的%%
    if (*(percent + 1) == '%') {
        size_t prefix_len = percent - fmt + 2;
        char prefix[prefix_len + 1];
        strncpy(prefix, fmt, prefix_len);
        prefix[prefix_len] = '\0';

        char rest_buf[buf_size];
        int rest_len = sprintf_step(rest_buf, buf_size, percent + 2, args);
        if (rest_len < 0) return rest_len;

        return snprintf(buf, buf_size, "%s%s", prefix, rest_buf);
    }

    // 提取完整格式说明符(支持带修饰符的格式如%5.2f)
    char spec[16] = {0};
    char *spec_end = percent + 1;
    // 跳过格式修饰符(数字、.、l等)
    while ((*spec_end >= '0' && *spec_end <= '9') || *spec_end == '.' || *spec_end == 'l') {
        spec_end++;
    }
    // 复制完整格式符
    size_t spec_len = spec_end - percent + 1;
    strncpy(spec, percent, spec_len);

    // 格式化当前参数到临时缓冲区
    char val_buf[64];
    int val_len = vsnprintf(val_buf, sizeof(val_buf), spec, args);
    if (val_len < 0) {
        va_end(args);
        return val_len;
    }

    // 拼接前缀、替换值、后缀
    size_t prefix_len = percent - fmt;
    char prefix[prefix_len + 1];
    strncpy(prefix, fmt, prefix_len);
    prefix[prefix_len] = '\0';

    int result = snprintf(buf, buf_size, "%s%s%s", prefix, val_buf, spec_end);
    va_end(args);
    return result;
}

// 测试示例
int main() {
    char buf[256];
    const char *initial_str = "Temperature is %f, Humidity is %d, wait for %d secs";

    float temp = 23.45;
    sprintf_step(buf, sizeof(buf), initial_str, temp);
    printf("第一次替换后:%s\n", buf);

    char humidity = 87;
    sprintf_step(buf, sizeof(buf), buf, humidity);
    printf("第二次替换后:%s\n", buf);

    int time = 3;
    sprintf_step(buf, sizeof(buf), buf, time);
    printf("第三次替换后:%s\n", buf);

    return 0;
}

代码说明

  1. 格式符识别:支持带修饰符的格式(如%5.2f),通过遍历跳过数字、小数点等修饰符,准确定位格式类型符(f/d等)。
  2. 转义处理:自动跳过%%转义序列,避免误替换。
  3. 缓冲区安全:全程使用snprintf确保不会发生缓冲区溢出。

输出结果

第一次替换后:Temperature is 23.450000, Humidity is %d, wait for %d secs
第二次替换后:Temperature is 23.450000, Humidity is 87, wait for %d secs
第三次替换后:Temperature is 23.450000, Humidity is 87, wait for 3 secs

内容的提问来源于stack exchange,提问作者Sajid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 23:50:23