【问题标题】:C insert and replace string at positionC在位置插入和替换字符串
【发布时间】:2019-06-21 00:02:48
【问题描述】:

如何将一个字符串(源)插入到 C 中的另一个字符串(dest)的特定位置,覆盖目标字符串(而不是在插入位置移动目标字符串的内容)。

下面抽象出string_insert_and_replace等函数;

char str_dest[] = "abcdefg";
char str_source[] = "123";

//The 3rd argument is the position to insert at
string_insert_and_replace(str_dest, str_source, 3);

//str_dest should now be "abc123g"

【问题讨论】:

标签: c string.h


【解决方案1】:

如果想要长字符串的性能,请考虑memcpy,它可能已针对架构进行了优化。

#include <string.h> /* memcpy strlen */
#include <stdio.h>  /* printf */
#include <assert.h>

static void string_insert_and_replace(char *str_dest,
    const char *str_source, const size_t offset) {
    const size_t len_dest = strlen(str_dest), len_source = strlen(str_source);
    size_t n = len_source;
    assert(str_dest && str_source);
    if(offset + len_source > len_dest) {
        if(offset >= len_dest) return;
        n = len_dest - offset;
    }
    memcpy(str_dest + offset, str_source, n);
}

int main(void) {
    char str_dest[] = "abcdefg";
    char str_source[] = "123";

    /* The 3rd argument is the position to insert at */
    string_insert_and_replace(str_dest, str_source, 5);

    /* str_dest should now be "abc123g" */
    printf("%s\n", str_dest);

    return 0;
}

编辑:在前者中,如果source 超过了dest+offset,那么strlen 将毫无意义地超过可复制长度的末尾。修改以下内容以截断搜索。

#include <string.h> /* memchr memcpy strlen */
#include <stdio.h>  /* printf */
#include <assert.h>

static void string_insert_and_replace(char *str_dest,
    const char *str_source, const size_t offset) {
    const size_t len_dest = strlen(str_dest);
    size_t n;
    char *null_source;
    assert(str_dest && str_source);
    /* This is the maximum bytes it could copy without overflow. */
    if(offset >= len_dest) return;
    n = len_dest - offset;
    /* If source is shorter then the remaining dest. */
    if((null_source = memchr(str_source, '\0', n)))
        n = (size_t)(null_source - str_source);
    memcpy(str_dest + offset, str_source, n);
}

【讨论】:

    【解决方案2】:

    这是一个有效的版本。我还包括了一些单元测试:

    #include <stdio.h>
    #include <string.h>
    
    char str_dest[] = "abcdefg";
    char str_source[] = "123";
    
    int dlen;
    
    void
    replace(char *dst,char *src,int pos)
    {
    
        // find starting place in destination -- we must scan char-by-char in
        // case pos is larger than the destination string size
        for (;  (*dst != 0) && (pos > 0);  ++dst, --pos);
    
        // copy in source string until _it_ ends or we run out of room in the
        // destination
        for (;  (*dst != 0) && (*src != 0);  ++dst, ++src)
            *dst = *src;
    }
    
    void
    test(int pos)
    {
        char dst[dlen + 1];
    
        strcpy(dst,str_dest);
        replace(dst,str_source,pos);
    
        printf("POS: %d DST: '%s'\n",pos,dst);
    }
    
    int
    main(void)
    {
    
        dlen = strlen(str_dest);
    
        for (int pos = 0;  pos <= (dlen + 3);  ++pos)
            test(pos);
    
        return 0;
    }
    

    更新:

    我正在为微控制器编写此代码,安全检查会影响性能吗?

    是的,安全检查要求逐字节扫描destination字符串以定位结尾。

    请注意,没有需要对 source 字符串执行strlen。请参阅下面的函数的 string_replace_fast 变体。它并不安全,但 [大约 2 倍] 快。

    此外,我认为如果源字符串长度加上 pos 参数大于 strlen(dest),我将使用当前代码覆盖不属于 dest 字符串的内存。

    是的,没错。您可以在下面的测试结果中看到它。

    您可能不得不牺牲一点速度。如果这不是一个被称为 lot 的函数,那么选择更慢/更安全的版本。您只能通过一些基准测试来判断这一点。

    这是测试程序的修改版本,它为您的版本和我的版本进行了基准测试以及一两个变体:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    char str_dest[] = "abcdefghijklimnopqrstuvwxyz";
    char str_source[] = "123";
    char *tmp;
    
    int dlen;
    
    typedef void (*func_p)(char *dst,char *src,int pos);
    
    #define TIMEIT(_fnc,_pos) \
        timeit(_fnc,_pos,#_fnc)
    
    char *
    fixstr(const char *src)
    {
        static char fix[1000];
        char *dst = fix;
    
        for (;  *src != 0;  ++src) {
            if ((*src >= 0x20) && (*src <= 0x7E))
                *dst++ = *src;
            else
                dst += sprintf(dst,"{?%2.2X?}",*src & 0xFF);
        }
        *dst = 0;
    
        return fix;
    }
    
    double
    tvgetf(void)
    {
        struct timespec ts;
        double sec;
    
        clock_gettime(CLOCK_REALTIME,&ts);
        sec = ts.tv_nsec;
        sec /= 1e9;
        sec += ts.tv_sec;
    
        return sec;
    }
    
    void
    string_replace_pos(char *dest, char *source, int pos)
    {
        int source_length = strlen(source);
    
        for (int i = 0; i < source_length; i++) {
            dest[pos + i] = source[i];
        }
    }
    
    void
    string_replace_fast(char *dest, char *source, int pos)
    {
        int chr;
    
        dest += pos;
        for (chr = *source++;  chr != 0;  chr = *source++, ++dest)
            *dest = chr;
    }
    
    void
    replace(char *dst,char *src,int pos)
    {
    
        // find starting place in destination -- we must scan char-by-char in
        // case pos is larger than the destination string size
        for (;  (*dst != 0) && (pos > 0);  ++dst, --pos);
    
        // copy in source string until _it_ ends or we run out of room in the
        // destination
        for (;  (*dst != 0) && (*src != 0);  ++dst, ++src)
            *dst = *src;
    }
    
    void
    replace2(char *dst,char *src,int pos)
    {
        int mlen = strlen(dst);
    
        // find starting place in destination -- we must scan char-by-char in
        // case pos is larger than the destination string size
        if (pos <= mlen)
            dst += pos;
    
        // copy in source string until _it_ ends or we run out of room in the
        // destination
        for (;  (*dst != 0) && (*src != 0);  ++dst, ++src)
            *dst = *src;
    }
    
    void
    timeit(func_p func,int pos,const char *name)
    {
        double tvbeg;
    
        strcpy(tmp,str_dest);
        tvbeg = tvgetf();
    
        for (int iter = 1;  iter <= 1000;  ++iter)
            func(tmp,str_source,pos);
    
        tvbeg = tvgetf() - tvbeg; \
    
        printf("POS: %d %.9f DST: '%s' (%s)\n",
            pos,tvbeg,fixstr(tmp),name);
    
        int clen = strlen(tmp);
        if (clen != dlen)
            printf("ERROR: length mismatch -- EXPECTED: %d ACTUAL: %d\n",dlen,clen);
    }
    
    void
    test(int pos)
    {
    
        printf("\n");
        TIMEIT(string_replace_pos,pos);
        TIMEIT(string_replace_fast,pos);
        TIMEIT(replace,pos);
        TIMEIT(replace2,pos);
    }
    
    int
    main(void)
    {
    
        dlen = strlen(str_dest);
        tmp = malloc(dlen + 100);
    
        for (int pos = -3;  pos <= (dlen + 3);  ++pos)
            test(pos);
    
        return 0;
    }
    

    这是这个测试程序的输出。

    注意您的版本的错误行。另外,请注意如果插入位置为负数会发生什么。

    POS: -3 0.000008106 DST: 'abcdefghijklimnopqrstuvwxyz' (string_replace_pos)
    POS: -3 0.000003815 DST: 'abcdefghijklimnopqrstuvwxyz' (string_replace_fast)
    POS: -3 0.000007629 DST: '123defghijklimnopqrstuvwxyz' (replace)
    POS: -3 0.000011683 DST: 'abcdefghijklimnopqrstuvwxyz' (replace2)
    
    POS: -2 0.000007153 DST: '3bcdefghijklimnopqrstuvwxyz' (string_replace_pos)
    POS: -2 0.000003815 DST: '3bcdefghijklimnopqrstuvwxyz' (string_replace_fast)
    POS: -2 0.000007391 DST: '123defghijklimnopqrstuvwxyz' (replace)
    POS: -2 0.000012159 DST: '3bcdefghijklimnopqrstuvwxyz' (replace2)
    
    POS: -1 0.000007391 DST: '23cdefghijklimnopqrstuvwxyz' (string_replace_pos)
    POS: -1 0.000003815 DST: '23cdefghijklimnopqrstuvwxyz' (string_replace_fast)
    POS: -1 0.000007391 DST: '123defghijklimnopqrstuvwxyz' (replace)
    POS: -1 0.000012159 DST: '23cdefghijklimnopqrstuvwxyz' (replace2)
    
    POS: 0 0.000007391 DST: '123defghijklimnopqrstuvwxyz' (string_replace_pos)
    POS: 0 0.000004053 DST: '123defghijklimnopqrstuvwxyz' (string_replace_fast)
    POS: 0 0.000007391 DST: '123defghijklimnopqrstuvwxyz' (replace)
    POS: 0 0.000012159 DST: '123defghijklimnopqrstuvwxyz' (replace2)
    
    POS: 1 0.000007391 DST: 'a123efghijklimnopqrstuvwxyz' (string_replace_pos)
    POS: 1 0.000003815 DST: 'a123efghijklimnopqrstuvwxyz' (string_replace_fast)
    POS: 1 0.000008583 DST: 'a123efghijklimnopqrstuvwxyz' (replace)
    POS: 1 0.000012159 DST: 'a123efghijklimnopqrstuvwxyz' (replace2)
    
    POS: 2 0.000007153 DST: 'ab123fghijklimnopqrstuvwxyz' (string_replace_pos)
    POS: 2 0.000003815 DST: 'ab123fghijklimnopqrstuvwxyz' (string_replace_fast)
    POS: 2 0.000010014 DST: 'ab123fghijklimnopqrstuvwxyz' (replace)
    POS: 2 0.000012159 DST: 'ab123fghijklimnopqrstuvwxyz' (replace2)
    
    POS: 3 0.000007391 DST: 'abc123ghijklimnopqrstuvwxyz' (string_replace_pos)
    POS: 3 0.000003815 DST: 'abc123ghijklimnopqrstuvwxyz' (string_replace_fast)
    POS: 3 0.000011206 DST: 'abc123ghijklimnopqrstuvwxyz' (replace)
    POS: 3 0.000015497 DST: 'abc123ghijklimnopqrstuvwxyz' (replace2)
    
    POS: 4 0.000007629 DST: 'abcd123hijklimnopqrstuvwxyz' (string_replace_pos)
    POS: 4 0.000004053 DST: 'abcd123hijklimnopqrstuvwxyz' (string_replace_fast)
    POS: 4 0.000013351 DST: 'abcd123hijklimnopqrstuvwxyz' (replace)
    POS: 4 0.000012636 DST: 'abcd123hijklimnopqrstuvwxyz' (replace2)
    
    POS: 5 0.000007629 DST: 'abcde123ijklimnopqrstuvwxyz' (string_replace_pos)
    POS: 5 0.000004053 DST: 'abcde123ijklimnopqrstuvwxyz' (string_replace_fast)
    POS: 5 0.000014544 DST: 'abcde123ijklimnopqrstuvwxyz' (replace)
    POS: 5 0.000012636 DST: 'abcde123ijklimnopqrstuvwxyz' (replace2)
    
    POS: 6 0.000007391 DST: 'abcdef123jklimnopqrstuvwxyz' (string_replace_pos)
    POS: 6 0.000004053 DST: 'abcdef123jklimnopqrstuvwxyz' (string_replace_fast)
    POS: 6 0.000015736 DST: 'abcdef123jklimnopqrstuvwxyz' (replace)
    POS: 6 0.000012636 DST: 'abcdef123jklimnopqrstuvwxyz' (replace2)
    
    POS: 7 0.000007629 DST: 'abcdefg123klimnopqrstuvwxyz' (string_replace_pos)
    POS: 7 0.000004053 DST: 'abcdefg123klimnopqrstuvwxyz' (string_replace_fast)
    POS: 7 0.000018358 DST: 'abcdefg123klimnopqrstuvwxyz' (replace)
    POS: 7 0.000012636 DST: 'abcdefg123klimnopqrstuvwxyz' (replace2)
    
    POS: 8 0.000007629 DST: 'abcdefgh123limnopqrstuvwxyz' (string_replace_pos)
    POS: 8 0.000004053 DST: 'abcdefgh123limnopqrstuvwxyz' (string_replace_fast)
    POS: 8 0.000019550 DST: 'abcdefgh123limnopqrstuvwxyz' (replace)
    POS: 8 0.000012636 DST: 'abcdefgh123limnopqrstuvwxyz' (replace2)
    
    POS: 9 0.000007629 DST: 'abcdefghi123imnopqrstuvwxyz' (string_replace_pos)
    POS: 9 0.000003815 DST: 'abcdefghi123imnopqrstuvwxyz' (string_replace_fast)
    POS: 9 0.000020504 DST: 'abcdefghi123imnopqrstuvwxyz' (replace)
    POS: 9 0.000012636 DST: 'abcdefghi123imnopqrstuvwxyz' (replace2)
    
    POS: 10 0.000007629 DST: 'abcdefghij123mnopqrstuvwxyz' (string_replace_pos)
    POS: 10 0.000003815 DST: 'abcdefghij123mnopqrstuvwxyz' (string_replace_fast)
    POS: 10 0.000032425 DST: 'abcdefghij123mnopqrstuvwxyz' (replace)
    POS: 10 0.000012159 DST: 'abcdefghij123mnopqrstuvwxyz' (replace2)
    
    POS: 11 0.000007391 DST: 'abcdefghijk123nopqrstuvwxyz' (string_replace_pos)
    POS: 11 0.000003815 DST: 'abcdefghijk123nopqrstuvwxyz' (string_replace_fast)
    POS: 11 0.000021696 DST: 'abcdefghijk123nopqrstuvwxyz' (replace)
    POS: 11 0.000012159 DST: 'abcdefghijk123nopqrstuvwxyz' (replace2)
    
    POS: 12 0.000007391 DST: 'abcdefghijkl123opqrstuvwxyz' (string_replace_pos)
    POS: 12 0.000003815 DST: 'abcdefghijkl123opqrstuvwxyz' (string_replace_fast)
    POS: 12 0.000022888 DST: 'abcdefghijkl123opqrstuvwxyz' (replace)
    POS: 12 0.000012159 DST: 'abcdefghijkl123opqrstuvwxyz' (replace2)
    
    POS: 13 0.000007391 DST: 'abcdefghijkli123pqrstuvwxyz' (string_replace_pos)
    POS: 13 0.000003815 DST: 'abcdefghijkli123pqrstuvwxyz' (string_replace_fast)
    POS: 13 0.000023842 DST: 'abcdefghijkli123pqrstuvwxyz' (replace)
    POS: 13 0.000012159 DST: 'abcdefghijkli123pqrstuvwxyz' (replace2)
    
    POS: 14 0.000007153 DST: 'abcdefghijklim123qrstuvwxyz' (string_replace_pos)
    POS: 14 0.000003815 DST: 'abcdefghijklim123qrstuvwxyz' (string_replace_fast)
    POS: 14 0.000024796 DST: 'abcdefghijklim123qrstuvwxyz' (replace)
    POS: 14 0.000015736 DST: 'abcdefghijklim123qrstuvwxyz' (replace2)
    
    POS: 15 0.000007391 DST: 'abcdefghijklimn123rstuvwxyz' (string_replace_pos)
    POS: 15 0.000003815 DST: 'abcdefghijklimn123rstuvwxyz' (string_replace_fast)
    POS: 15 0.000025749 DST: 'abcdefghijklimn123rstuvwxyz' (replace)
    POS: 15 0.000015497 DST: 'abcdefghijklimn123rstuvwxyz' (replace2)
    
    POS: 16 0.000007153 DST: 'abcdefghijklimno123stuvwxyz' (string_replace_pos)
    POS: 16 0.000003815 DST: 'abcdefghijklimno123stuvwxyz' (string_replace_fast)
    POS: 16 0.000026941 DST: 'abcdefghijklimno123stuvwxyz' (replace)
    POS: 16 0.000015497 DST: 'abcdefghijklimno123stuvwxyz' (replace2)
    
    POS: 17 0.000007153 DST: 'abcdefghijklimnop123tuvwxyz' (string_replace_pos)
    POS: 17 0.000003815 DST: 'abcdefghijklimnop123tuvwxyz' (string_replace_fast)
    POS: 17 0.000027895 DST: 'abcdefghijklimnop123tuvwxyz' (replace)
    POS: 17 0.000015497 DST: 'abcdefghijklimnop123tuvwxyz' (replace2)
    
    POS: 18 0.000007153 DST: 'abcdefghijklimnopq123uvwxyz' (string_replace_pos)
    POS: 18 0.000004053 DST: 'abcdefghijklimnopq123uvwxyz' (string_replace_fast)
    POS: 18 0.000028849 DST: 'abcdefghijklimnopq123uvwxyz' (replace)
    POS: 18 0.000015497 DST: 'abcdefghijklimnopq123uvwxyz' (replace2)
    
    POS: 19 0.000007153 DST: 'abcdefghijklimnopqr123vwxyz' (string_replace_pos)
    POS: 19 0.000003815 DST: 'abcdefghijklimnopqr123vwxyz' (string_replace_fast)
    POS: 19 0.000029802 DST: 'abcdefghijklimnopqr123vwxyz' (replace)
    POS: 19 0.000015497 DST: 'abcdefghijklimnopqr123vwxyz' (replace2)
    
    POS: 20 0.000007391 DST: 'abcdefghijklimnopqrs123wxyz' (string_replace_pos)
    POS: 20 0.000003815 DST: 'abcdefghijklimnopqrs123wxyz' (string_replace_fast)
    POS: 20 0.000030994 DST: 'abcdefghijklimnopqrs123wxyz' (replace)
    POS: 20 0.000015497 DST: 'abcdefghijklimnopqrs123wxyz' (replace2)
    
    POS: 21 0.000007153 DST: 'abcdefghijklimnopqrst123xyz' (string_replace_pos)
    POS: 21 0.000003815 DST: 'abcdefghijklimnopqrst123xyz' (string_replace_fast)
    POS: 21 0.000031948 DST: 'abcdefghijklimnopqrst123xyz' (replace)
    POS: 21 0.000015497 DST: 'abcdefghijklimnopqrst123xyz' (replace2)
    
    POS: 22 0.000007153 DST: 'abcdefghijklimnopqrstu123yz' (string_replace_pos)
    POS: 22 0.000003815 DST: 'abcdefghijklimnopqrstu123yz' (string_replace_fast)
    POS: 22 0.000032902 DST: 'abcdefghijklimnopqrstu123yz' (replace)
    POS: 22 0.000015497 DST: 'abcdefghijklimnopqrstu123yz' (replace2)
    
    POS: 23 0.000007391 DST: 'abcdefghijklimnopqrstuv123z' (string_replace_pos)
    POS: 23 0.000003815 DST: 'abcdefghijklimnopqrstuv123z' (string_replace_fast)
    POS: 23 0.000034094 DST: 'abcdefghijklimnopqrstuv123z' (replace)
    POS: 23 0.000015497 DST: 'abcdefghijklimnopqrstuv123z' (replace2)
    
    POS: 24 0.000007153 DST: 'abcdefghijklimnopqrstuvw123' (string_replace_pos)
    POS: 24 0.000003815 DST: 'abcdefghijklimnopqrstuvw123' (string_replace_fast)
    POS: 24 0.000034571 DST: 'abcdefghijklimnopqrstuvw123' (replace)
    POS: 24 0.000015497 DST: 'abcdefghijklimnopqrstuvw123' (replace2)
    
    POS: 25 0.000007153 DST: 'abcdefghijklimnopqrstuvwx123' (string_replace_pos)
    ERROR: length mismatch -- EXPECTED: 27 ACTUAL: 28
    POS: 25 0.000003815 DST: 'abcdefghijklimnopqrstuvwx123' (string_replace_fast)
    ERROR: length mismatch -- EXPECTED: 27 ACTUAL: 28
    POS: 25 0.000034571 DST: 'abcdefghijklimnopqrstuvwx12' (replace)
    POS: 25 0.000014305 DST: 'abcdefghijklimnopqrstuvwx12' (replace2)
    
    POS: 26 0.000007153 DST: 'abcdefghijklimnopqrstuvwxy123' (string_replace_pos)
    ERROR: length mismatch -- EXPECTED: 27 ACTUAL: 29
    POS: 26 0.000003815 DST: 'abcdefghijklimnopqrstuvwxy123' (string_replace_fast)
    ERROR: length mismatch -- EXPECTED: 27 ACTUAL: 29
    POS: 26 0.000034809 DST: 'abcdefghijklimnopqrstuvwxy1' (replace)
    POS: 26 0.000012636 DST: 'abcdefghijklimnopqrstuvwxy1' (replace2)
    
    POS: 27 0.000007391 DST: 'abcdefghijklimnopqrstuvwxyz123' (string_replace_pos)
    ERROR: length mismatch -- EXPECTED: 27 ACTUAL: 30
    POS: 27 0.000003815 DST: 'abcdefghijklimnopqrstuvwxyz123' (string_replace_fast)
    ERROR: length mismatch -- EXPECTED: 27 ACTUAL: 30
    POS: 27 0.000148058 DST: 'abcdefghijklimnopqrstuvwxyz' (replace)
    POS: 27 0.000008821 DST: 'abcdefghijklimnopqrstuvwxyz' (replace2)
    
    POS: 28 0.000007629 DST: 'abcdefghijklimnopqrstuvwxyz' (string_replace_pos)
    POS: 28 0.000003815 DST: 'abcdefghijklimnopqrstuvwxyz' (string_replace_fast)
    POS: 28 0.000039339 DST: 'abcdefghijklimnopqrstuvwxyz' (replace)
    POS: 28 0.000012159 DST: '123defghijklimnopqrstuvwxyz' (replace2)
    
    POS: 29 0.000007391 DST: 'abcdefghijklimnopqrstuvwxyz' (string_replace_pos)
    POS: 29 0.000003815 DST: 'abcdefghijklimnopqrstuvwxyz' (string_replace_fast)
    POS: 29 0.000035048 DST: 'abcdefghijklimnopqrstuvwxyz' (replace)
    POS: 29 0.000011921 DST: '123defghijklimnopqrstuvwxyz' (replace2)
    
    POS: 30 0.000007153 DST: 'abcdefghijklimnopqrstuvwxyz' (string_replace_pos)
    POS: 30 0.000003815 DST: 'abcdefghijklimnopqrstuvwxyz' (string_replace_fast)
    POS: 30 0.000035048 DST: 'abcdefghijklimnopqrstuvwxyz' (replace)
    POS: 30 0.000012159 DST: '123defghijklimnopqrstuvwxyz' (replace2)
    

    【讨论】:

    • 有趣的实现,这就是我所做的,同样的事情,但没有任何安全性。我正在为微控制器编写此代码,安全检查会影响性能吗?另外我认为,如果源字符串长度加上 pos 参数大于 strlen(dest),则使用当前代码我将覆盖不属于 dest 字符串的内存。 void string_replace_pos(char dest[], char source[], char pos) { int source_length = strlen(source); for(int i = 0; i &lt; source_length; i++) { dest[pos + i] = source[i]; } }
    • 尊敬的 Estey 先生,先生,我以前得到了您的很多帮助。现在我需要,我也需要你的帮助。如果你能在我的简单程序上看到问题,我真的很感激你。我在文件开头将其解释为注释。正如我在评论中解释的那样,我的问题仅仅是“使用”管道。我期待着您的回音。 C 文件是snrkr.com/soner_aid.cBest Regards。
    【解决方案3】:

    由于字符串是指向其第一个字符的指针,如果您知道要写入哪个索引,则可以这样做:

    void string_insert_and_replace(char *dest, char *src, size_t pos)
    {
        while (*src)
        {
            *(dest + pos) = *src;
            dest++, src++;
        }
    }
    

    假设dest 中有足够的空间来容纳整个pos + strlen(src) + 1(我认为)。

    【讨论】:

    • 我想到了类似的东西。在此处添加另一个答案,只是修改为使用 while 循环。当空间不足时,额外的检查会阻止写入 dest 字符串。 ``` void string_replace_pos(char dest[], char source[], char pos) { while((*dest != '\0') && (pos > 0)) { dest++;正--; } while((*dest != '\0') && (*source != '\0')) { *dest = *source;目的地++;源++; } } ```
    【解决方案4】:

    当您抽象任何字符串函数时,您应该始终尽可能少地提供任何目标缓冲区的可用大小,并尽可能提供源缓冲区的最大大小,以避免字符串缺少空终止符的问题。

    这意味着类似

    void string_insert_and_replace(char *dest, int dlen, const char *src, int slen, int off)
    {
        ...
    }
    

    如果您发现自己使用 strcpy 和/或 strlen 而不是 strncpystrnlen,那么您做错了。忽略任何甚至建议这样做的代码。

    【讨论】:

    • 关于strn* 系列函数的有趣评论。您可能会发现this question 上的讨论很有趣。
    • 确实如此。事实上,出于该线程中提到的原因,我通常使用 xsnprintf() 或 snprintf() 而不是 strncpy()。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    • 2013-02-16
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多