tags:

views:

116

answers:

5

Is there any buildin function or a alternative simple and fast way of escape a C character array that if used with e.g printf should yield original character array again.

char* str = "\tHello World\n";
char* escaped_str = escape(str); //should contain "\tHello World\n" with char \ ,t.
printf(escaped_str); //should print out [TAB]Hello World[nextline] similar to if str was printed.

Is there a simple way in c to escape a string with c escape characters.

Update

I have buffer containing a string with escape character. And i want to include in a C file. For that i need to escape it so it can be complied. I just need to know if there is simple way of doing it instead of scanning the buffer for \n \t etc and generating there c escape char.

for(int i=0; i< strlen(buffer);i++)
    if(buffer[i]=='\n')
      sprintf(dest,"\\n")
    else ....

Update 2

I wrote this function. It work fine.

char* escape(char* buffer){
    int i,j;
    int l = strlen(buffer) + 1;
    char esc_char[]= { '\a','\b','\f','\n','\r','\t','\v','\\'};
    char essc_str[]= {  'a', 'b', 'f', 'n', 'r', 't', 'v','\\'};
  char* dest  =  (char*)calloc( l*2,sizeof(char));
    char* ptr=dest;
    for(i=0;i<l;i++){
        for(j=0; j< 8 ;j++){
            if( buffer[i]==esc_char[j] ){
              *ptr++ = '\\';
              *ptr++ = essc_str[j];
                 break;
            }
        }
        if(j == 8 )
      *ptr++ = buffer[i];
    }
  *ptr='\0';
    return dest;
}
+2  A: 

No, there isn't any standard function for creating the source code version of the string. But you could use the iscntrl function to write one, or just use the switch keyword.

But, unless your program writes out a C source file intended to be run through the compiler, you don't need to work with escaped strings. printf doesn't process character escape sequences, only variable insertions (%d, %s, etc)

Specifically, the following produce the same output:

printf("\tHello World\n");

and

const char* str = "\tHello World\n";
printf(str);

and

const char* str = "\tHello World\n";
printf("%s", str);

The second one isn't a good idea, because if str contained % your program would produce bad output and could crash.

EDIT: For producing the source code version, there are a couple of approaches:

Simpler, but less readable output:

if (isctrl(ch) || ch == '\\' || ch == '\"' || ch == '\'') {
   fprintf(outf, "\\x%02x", ch);
}
else
   fputc(outf, ch);

More readable results:

switch (ch) {
  case '\"':
    fputs(outf, "\\\"");
    break;
  case '\'':
    fputs(outf, "\\\'");
    break;
  case '\\':
    fputs(outf, "\\\\");
    break;
  case '\a':
    fputs(outf, "\\a");
    break;
  case '\b':
    fputs(outf, "\\a");
    break;
  case '\n':
    fputs(outf, "\\n");
    break;
  case '\t':
    fputs(outf, "\\t");
    break;
  // and so on
  default:
    fputc(outf, ch);
}
Ben Voigt
yup that will work. In mean time i wrote mine own too. check that out as well logic is very similar to yours. But it print out actual \n instead of it hex equivalent. but your second solution is very similar
affan
We both overlooked `"` and `'`, which will really confuse the compiler if you forget to escape them. Now fixed in my examples.
Ben Voigt
thanks for that. I missed it.
affan
A: 

The only escaping you need to do is replacing each occurrence of "%" with "%%"; "%" is the ONLY character that printf treats specially. The "\" escapes have nothing to do with printf; they're part of the C compiler's compile-time processing of string literals.

R..
With the updated description of your problem (you're trying to escape strings for use in C source, not for printf) my answer is not so useful.
R..
A: 

Please checks the paper on printf

You need to know more about the escape sequences.

Praveen S
Paper is misleading. The entire first page and part of the second have nothing to do with printf but with the C compiler and string literals.
R..
A: 

If you don't require the resulting string to be human-readable, and your compile-time character set is the same as your execution character set, then the simplest way is to use code point escapes for everything:

int print_string_literal(char *s)
{
    putchar('\"');

    while (*s)
    {
        unsigned cp = (unsigned char)*s++;
        printf("\\x%.2x", cp);
    }

    putchar('\"');
}

You could finess this some to produce nicer looking strings, but you did ask for something simple...

caf
A: 

If you're generating a string to be used as part of a C source file, then quoting is quite complex (you have to deal with newlines, several other control characters, quotes, backslashes etc). It's much quicker and easier to use the fact that a string is simply an array of integer-like values - rather than

char generated_file_str[] = "ABC\n\";

generate

char generated_file_str[] = {65,66,67,10,0};

This is fairly easy to write - something like:

printf("char generated_string[] = {");
for (i = 0; i < length; i++) {
    printf("%d, ", str[i]);
}
printf("0};\n");
psmears