用于转义字符串的标准c库

时间:2010-04-27 21:47:47

标签: c string escaping

是否有标准C库函数来转义C字符串?

例如,如果我有C字符串:

char example[] = "first line\nsecond line: \"inner quotes\"";

我想打印

"first line\nsecond line: \"inner quotes\""

是否有一个库函数可以为我进行转换?滚动我自己似乎有点傻。

奖励积分,如果我可以给它一个长度来逃避(因此它在\0之前或之后停止。)

7 个答案:

答案 0 :(得分:3)

答案 1 :(得分:2)

没有标准的C库函数。

使用声明时

char example[] = "first line\nsecond line: \"inner quotes\"";

转义序列将被编译器解释和替换。你将不得不“解释”C逃脱的角色。这是一个快速肮脏的例子:

#include <stdio.h>
#include <ctype.h>

void print_unescaped(char* ptr, int len) {
    if (!ptr) return;
    for (int i = 0; i < len; i++, ptr++) {
        switch (*ptr) {
            case '\0': printf("\\0");  break;
            case '\a': printf("\\a");  break;
            case '\b': printf("\\b");  break;
            case '\f': printf("\\f");  break;
            case '\n': printf("\\n");  break;
            case '\r': printf("\\r");  break;
            case '\t': printf("\\t");  break;
            case '\v': printf("\\v");  break;
            case '\\': printf("\\\\"); break;
            case '\?': printf("\\\?"); break;
            case '\'': printf("\\\'"); break;
            case '\"': printf("\\\""); break;
            default:
                if (isprint(*ptr)) printf("%c",     *ptr);
                else               printf("\\%03o", *ptr);
        }
    }
}

答案 2 :(得分:1)

您刚才提到要打印字符串。

char example[] = "first line\nsecond line: \"inner quotes\"";
size_t len = strlen(example);
size_t i;

static const char *simple = "\\\'\"";
static const char *complex = "\a\b\f\n\r\t\v";
static const char *complexMap = "abfnrtv";

for (i = 0; i < length; i++)
{
    char *p;
    if (strchr(simple, example[i]))
    {
        putchar('\\');
        putchar(example[i]);
    }
    else if ((p = strchr(complex, example[i]))
    {
        size_t idx = p - complex;
        putchar('\\');
        putchar(complexMap[idx]);
    }
    else if (isprint(example[i]))
    {
        putchar(example[i]);
    }
    else
    {
        printf("\\%03o", example[i]);
    }
}

答案 3 :(得分:0)

没有标准的C功能,但不是很难推出自己的

没什么太漂亮但是: -

void escape_str(char *dest, char *src)
{
     *dest = 0;
     while(*src)
     {
         switch(*src)
         {
             case '\n' : strcat(dest++, "\\n"); break;
             case '\"' : strcat(dest++, "\\\""); break;
             default:  *dest = *src;
         }
         *src++;
         *dest++;
         *dest = 0;                     
     }
}

答案 4 :(得分:0)

#include <string.h>    
/* int c_quote(const char* src, char* dest, int maxlen)
 *
 * Quotes the string given so that it will be parseable by a c compiler.
 * Return the number of chars copied to the resulting string (including any nulls)
 *
 * if dest is NULL, no copying is performed, but the number of chars required to 
 * copy will be returned.
 *
 * maxlen characters are copied. If maxlen is negative, 
 * strlen is used to find the length of the source string, and the whole string
 * including the NULL-terminator is copied.
 *
 * Note that this function will not null-terminate the string in dest.
 * If the string in src is not null-terminated, or maxlen is specified to not
 * include the whole src, remember to null-terminate dest afterwards.
 *
 */
int c_quote(const char* src, char* dest, int maxlen) {
    int count = 0;
    if(maxlen < 0) {
        maxlen = strlen(src)+1;      /* add 1 for NULL-terminator */
    }

    while(src  && maxlen > 0) {
        switch(*src) {

            /* these normal, printable chars just need a slash appended */
            case '\\':
            case '\"':
            case '\'':
                if(dest) {
                    *dest++ = '\\';
                    *dest++ = *src;
                }
                count += 2;
                break; 

            /* newlines/tabs and unprintable characters need a special code.
             * Use the macro CASE_CHAR defined below.
             * The first arg for the macro is the char to compare to,
             * the 2nd arg is the char to put in the result string, after the '\' */
#define CASE_CHAR(c, d) case c:\
    if(dest) {\
        *dest++ = '\\'; *dest++ = (d);\
        }\
count += 2;\
break;
            /* --------------  */
            CASE_CHAR('\n', 'n');
            CASE_CHAR('\t', 't');
            CASE_CHAR('\b', 'b');
            /*  ------------- */

#undef CASE_CHAR


            /* by default, just copy the char over */
            default:
                if(dest) {
                    *dest++ = *src;
                }
                count++;
        }

        ++src;
        --maxlen;
    }
    return count;
}

答案 5 :(得分:0)

我觉得我之前的回答是作弊,因为写入缓冲区的函数比只写入stdout的函数更有用,所以这里有一个替代解决方案,可以计算出{{1}需要多少内存。 {1}}为dst,并根据要求停在NULL

所有dstLen检查都可能效率不高。

if(dst)

答案 6 :(得分:-2)

while(*src++)
{
  if(*src == '\\' || *src == '\"' || *src == '\'')
    *dest++ = '\\';

  *dest++ = *src++;
}
相关问题