这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » 字符串连接还能这么玩

共3条 1/1 1 跳转至

字符串连接还能这么玩

院士
2026-07-16 10:35:28     打赏
字符串连接还能这么玩

在项目开发中经常会遇到要将两个字符串连接的情况,而通常的作法往往是使用:

sprintf(buf, "%s%s", str_a, str_b);

记得要使用sprintf()函数则需要添加<stdio.h>的头文件。

在内存中执行格式化输入输出的stdio接口sprintf(),首先会调用fmemopen()函数构造一个基于内存的FILE对象,然后,调用fprintf()等函数完成最终的格式化输入输出功能,最后销毁临时构建的FILE对象。因此,这些接口的开销较大;无论从空间复杂度看还是从时间复杂度看,都远大于strcat()、strcpy()等函数。因此,如果只是想完成字符串的串接大可不必调用STDIO接口,而应该调用其它的标准库函数。比如下方方法:

strcpy(buf, str_a);
strcat(buf, str_b);

如果对性能仍不满足,则可以进一步优化以上字符串串接代码。strcat()首先会找到str_a的尾部,然后复制str_b的内容直到字符串末尾。但实际上,strcpy()函数在其内部实现中一定已经循环到了str_a的尾部,故而也知道str_a中签字串的尾部地址。然后,strcpy()函数并没有返回str_a中指向字符串尾部的指针,返回的却是buf本身。幸好,为满足这一需求,标准库特意增加了一个接口stpcpy(),该接口复制字符串并返回指向其尾部的指针:

#include <string.h>

char *stpcpy(char *dest, const char *src);

我们可以进一步优化以上用来串接两个字符串的代码:

// sprintf(buf, "%s%s", str_a, str_b);
char *p = stpcpy(buf, str_a);
strcpy(p, str_b);



关键词: 字符串     stpcpy    

专家
2026-07-17 10:21:15     打赏
2楼

效率这一点没注意到。习惯了sprintf,没想到会是这个情况。话说如果自己写变参函数,完成和printf一样的格式化处理,有没有sprintf一样的问题?比如

void formatComStr(unsigned char column, unsigned char page, const char *format, ...) {
    //char buffer[256];
    char temp[12];
    va_list args;
    char *p;
    int num;
    int i;
    char *str;
    int arg_int;
    unsigned int hex_num;
    char hex_chars[] = "0123456789ABCDEF";
    
    // 初始化
    p = buffer;
    buffer[0] = '\0';
    
    va_start(args, format);
    
    while(*format) {
        if(*format == '%') {
            format++;
            switch(*format) {
                case 'd':
                    num = va_arg(args, int);
                    if(num < 0) {
                        *p++ = '-';
                        num = -num;
                    }
                    i = 0;
                    if(num == 0) {
                        temp[i++] = '0';
                    } else {
                        while(num > 0) {
                            temp[i++] = '0' + (num % 10);
                            num /= 10;
                        }
                    }
                    while(i > 0) {
                        *p++ = temp[--i];
                    }
                    break;
                    
                case 's':
                    str = va_arg(args, char*);
                    while(*str) {
                        *p++ = *str++;
                    }
                    break;
                    
                case 'c':
                    arg_int = va_arg(args, int);
                    *p++ = (char)arg_int;
                    break;
                    
                // ========== 新增:十六进制支持 ==========
                case 'x':  // 小写十六进制
                case 'X': { // 大写十六进制
                    hex_num = va_arg(args, unsigned int);
                    
                    // 处理0的特殊情况
                    if(hex_num == 0) {
                        *p++ = '0';
                        break;
                    }
                    
                    // 转换为十六进制字符串
                    i = 0;
                    while(hex_num > 0 && i < 8) {
                        temp[i++] = hex_chars[hex_num & 0x0F];
                        hex_num >>= 4;
                    }
                    
                    // 反转输出
                    while(i > 0) {
                        *p++ = temp[--i];
                    }
                    break;
                }
                
                case '0': {
                    // 检查是否是 %02x 格式
                    format++;
                    if(*format == '2') {
                        format++;
                        if(*format == 'x' || *format == 'X') {
                            hex_num = va_arg(args, unsigned int);
                            // 始终输出2位十六进制
                            temp[0] = hex_chars[(hex_num >> 4) & 0x0F];
                            temp[1] = hex_chars[hex_num & 0x0F];
                            *p++ = temp[0];
                            *p++ = temp[1];
                            break;
                        }
                    }
                    // 如果不是 %02x,回退到默认
                    *p++ = '%';
                    *p++ = '0';
                    *p++ = *format;
                    break;
                }
                
                default:
                    *p++ = '%';
                    *p++ = *format;
                    break;
            }
        } else {
            *p++ = *format;
        }
        format++;
    }
    
    *p = '\0';
    va_end(args);
    
    printf(buffer);
}

这样的


助工
2026-07-17 09:20:53     打赏
3楼

这得啥项目上要把性能优化到这种程度啊?!


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]