带有特殊字符的字符串的控制台输出

Console output of strings with special characters

本文关键字:控制台 输出 字符串 特殊字符      更新时间:2023-10-16

是否有一种或多或少的标准方法来输出包含特殊字符的字符串,例如 ASCII 控制代码,以使输出是有效的 C/C++ 文字字符串,带有转义序列?

预期输出示例:Thisnisna\testnnShe said, "How are you?"n

如果不小心,输出将是

This
is
atest
She said, "How are you?"

不是想要的。

打印转义字符串显然很棘手。

问题包括

  1. 控制字符和空字符
  2. 义转义字符。
  3. 负面char .
  4. 十六进制转义序列没有指定的长度限制。 八进制限制为 3 位数字。

    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 = "abtnvfr"'?\";
      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);
      }
    }
    

迂腐:八进制转义序列在char范围超过 9 位的稀有机器上是一个问题。 这可以通过字符串级别的十六进制转义序列来处理,而不是在char基础上char处理,因为十六进制转义序列需要限制。 例:

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

根据您可能尝试实现的目标,我可以建议以下解决方案:只需将任何不可打印的字符替换为"\xnn"(nn 是字符的 ascii 代码。这将归结为

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

这当然不会使用像n(但x0a)这样的特殊缩写,但这应该不是问题。

如果它对某人有帮助,我很快就把它放在一起:

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;
        }
    }
}

(注意c < ' ' || c > '~'的潜在不可移植性,我想避免任何库引用)。