standard c library for escaping a string

前端 未结 7 1947
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-10 17:51

Is there a standard C library function to escape C-strings?

For example, if I had the C string:

char example[] = \"first line\\nsecond line: \\\"inne         


        
7条回答
  •  一生所求
    2020-12-10 18:21

    I felt like my previous answer was cheating because a function that writes to a buffer is much more useful than one that simply writes to stdout, so here's an alternative solution which works out how much memory one needs if dst is NULL, and also stops at dstLen as per the requirement.

    It's probably a little inefficient with all the if(dst) checking.

    #include 
    #include 
    #include 
    
    size_t str_escape(char *dst, const char *src, size_t dstLen)
    {
        const char complexCharMap[] = "abtnvfr";
    
        size_t i;
        size_t srcLen = strlen(src);    
        size_t dstIdx = 0;
    
        // If caller wants to determine required length (supplying NULL for dst)
        // then we set dstLen to SIZE_MAX and pretend the buffer is the largest
        // possible, but we never write to it. Caller can also provide dstLen
        // as 0 if no limit is wanted.
        if (dst == NULL || dstLen == 0) dstLen = SIZE_MAX;
    
        for (i = 0; i < srcLen && dstIdx < dstLen; i++)
        {
            size_t complexIdx = 0;
    
            switch (src[i])
            {
                case '\'':
                case '\"':
                case '\\':
                    if (dst && dstIdx <= dstLen - 2)
                    {
                        dst[dstIdx++] = '\\';
                        dst[dstIdx++] = src[i];
                    }
                    else dstIdx += 2;
                    break;
    
                case '\r': complexIdx++;
                case '\f': complexIdx++;
                case '\v': complexIdx++;
                case '\n': complexIdx++;
                case '\t': complexIdx++;
                case '\b': complexIdx++;
                case '\a':
                    if (dst && dstIdx <= dstLen - 2)
                    {
                        dst[dstIdx++] = '\\';
                        dst[dstIdx++] = complexCharMap[complexIdx];
                    }
                    else dstIdx += 2;
                    break;
    
                default:
                    if (isprint(src[i]))
                    {
                        // simply copy the character
                        if (dst)
                            dst[dstIdx++] = src[i];
                        else
                            dstIdx++;
                    }
                    else
                    {
                        // produce octal escape sequence
                        if (dst && dstIdx <= dstLen - 4)
                        {
                            dst[dstIdx++] = '\\';
                            dst[dstIdx++] = ((src[i] & 0300) >> 6) + '0';
                            dst[dstIdx++] = ((src[i] & 0070) >> 3) + '0';
                            dst[dstIdx++] = ((src[i] & 0007) >> 0) + '0';
                        }
                        else
                        {
                            dstIdx += 4;
                        }
                    }
            }
        }
    
        if (dst && dstIdx <= dstLen)
            dst[dstIdx] = '\0';
    
        return dstIdx;
    }
    

提交回复
热议问题