user1196549
user1196549

Reputation:

Console output of strings with special characters

Is there a more or less standard way to output character strings that contain special characters, such ASCII control codes, in such a way that the output is a valid C/C++ literal string, with escape sequences ?

Example of expected output: This\nis\na\\test\n\nShe said, \"How are you?\"\n

Without care, the output would be

This
is
a\test

She said, "How are you?"

not what want.

Upvotes: 1

Views: 2187

Answers (3)

user1196549
user1196549

Reputation:

If it helps someone, I have quickly put this together:

void printfe(char* string)
{
    for (char c= *string; c; c= *(++string))
    {
        switch (c)
        {
        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: (c < ' ' || c > '~') ? printf("\\%03o", c) : putchar(c); break;
        }
    }
}

(mind the potential non-portability of c < ' ' || c > '~', I wanted to avoid any library reference).

Upvotes: 0

chux
chux

Reputation: 153338

Printing escaped strings clearly is tricky.

Problems include

  1. Control characters and the null character.
  2. Escaping the escape character.
  3. Negative char.
  4. Hexadecimal escape sequence have no specified limit in length. Octal ones are limited to 3 digits.

    void EscapePrint(char ch) {
      // 1st handle all simple-escape-sequence C11 6.4.4.4
      // The important one to detect is the escape character `\`
      // Delete or adjust these 2 arrays per code's goals
      static const char *escapev = "\a\b\t\n\v\f\r\"\'\?\\";
      static const char *escapec = "abtnvfr\"\'\?\\";
      char *p = strchr(escapev, (unsigned char) ch);
      if (p && *p) {
        printf("\\%c", escapec[p - escapev]);
      }
    
      // if printable, just print it.
      else if (isprint((unsigned char) ch)) {
        fputc(ch, stdout);
      }
    
      // else use octal escape  
      else {
        // Use octal as hex is problematic reading back
        printf("\\%03hho", ch);
      }
    }
    

Pedantic: the octal escape sequence is a problem on rare machines whose char range exceeds 9 bits. This can be handled with a hex escaped sequences at the string level and not on a char by char basis as hex escaped sequences need a limit. Example:

  input 2 `char`:            \1 A
  //                               v----- intervening space
  output text including ":   "\\x1" "A"

Upvotes: 1

Ctx
Ctx

Reputation: 18410

Depending on what you might be trying to achieve I can suggest the following solution: Just replace any non-printable character with "\xnn" (nn being the ascii code of the character. This would boil down to

void myprint (char *s) {
   while (*s) {
      printf(isalnum((unsigned char) *s) ? "%c" : "\\%03hho", *s);
      s++;
   }
}

This will of course not use special abbreviations like \n (but \x0a) instead, but this shouldn't be a problem.

Upvotes: 0

Related Questions