如何在C中显式打印特殊字符?

时间:2015-04-06 18:35:57

标签: c printf

当我使用以下代码时:

#include <stdio.h>

int main(void)
{
    printf("%s","Hello world\nHello world");
    return 0;
}

打印为:

 Hello world
 Hello world

如何防止这种情况并将其作为C中的原始字符串文字打印?我的意思是它应该显示在终端窗口中,如下所示:

Hello world\nHello world

我知道我可以通过对printf使用反斜杠来实现这​​一点但是有没有其他C函数或方法来做到这一点而没有反斜杠?阅读文件时会有所帮助。

7 个答案:

答案 0 :(得分:5)

没有内置机制来执行此操作。你必须逐个字符手动完成。但是,ctype.h中的功能可能有所帮助。具体来说,在&#34; C&#34;在locale中,函数isprint保证对于基本执行字符集中的所有图形字符都是真的,这实际上与7位ASCII中的所有图形字符相同,加空间;并且保证对于7位ASCII中的所有控制字符都是如此,其中包括制表符,回车符等。

这是一幅草图:

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

int main(void)
{
    int x;
    setlocale(LC_ALL, "C"); // (1)

    while ((x = getchar()) != EOF)
    {
        unsigned int c = (unsigned int)(unsigned char)x; // (2)

        if (isprint(c) && c != '\\')
            putchar(c);
        else
            printf("\\x%02x", c);
    }
    return 0;
}

这不会逃避'也不会",但它会逃脱\,如果需要,可以直接扩展它。

为U + 000A打印\n,为U + 000D打印\r等,留作练习。处理基本执行字符集之外的字符(例如U + 0080到U + 10FFFF的UTF-8编码)也可以作为练习。

该程序包含两个完全符合标准的C库不需要的东西,但根据我的经验,在实际操作系统上是必要的。它们标有(1)(2)

1)这明确设置了&#39; locale&#39;配置默认设置假设的方式。

2)getchar返回的值为int假设unsigned char(通常为0-255)可表示范围内的数字,或特殊值EOF不< / em>在unsigned char)可表示的范围内。但是,已知有错误的C库为具有最高位设置的字符返回负数。如果发生这种情况,printf会在打印\xffffffa1时打印(例如)\xa1。将x投射到unsigned char然后再投回unsigned int会更正此问题。

答案 1 :(得分:1)

这样的事情可能就是你想要的。运行myprint(c)以打印字符C或其可打印的表示形式:

#include <ctype.h>

void myprint(int c)
{
    if (isprint(c))
        putchar(c); // just print printable characters
    else if (c == '\n')
        printf("\\n"); // display newline as \n
    else
        printf("%02x", c); // print everything else as a number
}

如果您使用的是Windows,我认为您的所有新行都是CRLF(回车,换行),因此它们将按照我编写该功能的方式打印为0d\n

答案 2 :(得分:0)

如果我理解了这个问题,如果你有一个包含控制字符的字符串,如换行符,制表符,退格键等,你想要打印这些字符的文本表示,而不是将它们解释为控制字符。

不幸的是,没有内置的printf转换说明符会为您执行此操作。你必须逐个字符地遍历字符串,测试每个字符串以查看它是否是一个控制字符,并为它写一些等效的文本。

这是一个快速,轻微测试的例子:

#include <stdio.h>
#include <limits.h>
#include <ctype.h>
...
char *src="This\nis\ta\btest";

char *lut[CHAR_MAX] = {0};  // look up table for printable equivalents
                            // of non-printable characters
lut['\n'] = "\\n";
lut['\t'] = "\\t";
lut['\b'] = "\\b";
...
for ( char *p = src; *p != 0; p++ )
{
  if ( isprint( *p ) )
    putchar( *p );
  else
    fputs( lut[ (int) *p], stdout ); // puts adds a newline at the end,
                                     // fputs does not.
}
putchar( '\n' );

答案 3 :(得分:0)

感谢用户 @chunk 为此答案做出贡献。

你为什么不写通用解决方案?这将使你在未来避免许多问题。

char *
str_escape(char str[])
{
    char chr[3];
    char *buffer = malloc(sizeof(char));
    unsigned int len = 1, blk_size;

    while (*str != '\0') {
        blk_size = 2;
        switch (*str) {
            case '\n':
                strcpy(chr, "\\n");
                break;
            case '\t':
                strcpy(chr, "\\t");
                break;
            case '\v':
                strcpy(chr, "\\v");
                break;
            case '\f':
                strcpy(chr, "\\f");
                break;
            case '\a':
                strcpy(chr, "\\a");
                break;
            case '\b':
                strcpy(chr, "\\b");
                break;
            case '\r':
                strcpy(chr, "\\r");
                break;
            default:
                sprintf(chr, "%c", *str);
                blk_size = 1;
                break;
        }
        len += blk_size;
        buffer = realloc(buffer, len * sizeof(char));
        strcat(buffer, chr);
        ++str;
    }
    return buffer;
}

它是如何工作的!

int
main(const int argc, const char *argv[])
{
    puts(str_escape("\tAnbms\n"));
    puts(str_escape("\tA\v\fZ\a"));
    puts(str_escape("txt \t\n\r\f\a\v 1 \t\n\r\f\a\v tt"));
    puts(str_escape("dhsjdsdjhs hjd hjds "));
    puts(str_escape(""));
    puts(str_escape("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\f\a\v"));
    puts(str_escape("\x0b\x0c\t\n\r\f\a\v"));
    puts(str_escape("\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14"));
}

输出

\tAnbms\n
\tA\v\fZ\a
txt \t\n\r\f\a\v 1 \t\n\r\f\a\v tt
dhsjdsdjhs hjd hjds 

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ \t\n\r\f\a\v
\v\f\t\n\r\f\a\v
\a\b\t\n\v\f\r

此解决方案基于维基百科https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences的信息 以及stackoverflow.com的其他用户的答案。

测试环境

$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 8.6 (jessie)
Release:    8.6
Codename:   jessie
$ uname -a
Linux localhost 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) x86_64 GNU/Linux
$ gcc --version
gcc (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

答案 4 :(得分:0)

仅使用putchar(specialCharName)。显示输入的特殊字符。

答案 5 :(得分:0)

  /// My experience Win 10 Code blocks GCC MinGW

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <windows.h>
///#include <threads.h>
#include <conio.h>
/// #include <dos.h>
#include <direct.h>

int main(void)

{
  /// This will give your desired result, turn string into Raw string :
  printf(R"(Hello world\nHello world)");
  printf(R"(Raw string support printing  *&^%$#@!~()_+-=,<.>/?:;"' )");
  printf("\n");
  printf(R"(.C with a Capital C file format does not support raw string )");
  printf("\n");
  printf(R"(.c with a small c file format does support raw string )");
  printf("\n");
  printf(R"( Raw string did not support \n new line )");
  printf("\n");

  printf(
      R"(More reading material at - https: // en.wikipedia.org/wiki/String_literal#Raw_strings;)");
  printf("\n");
  printf(
      R"(More reading material at - https: // en.wikipedia.org/wiki/String_literal;)");
  printf("\n");
  printf(
      R"(More reading material at - https://stackoverflow.com/questions/24850244/does-c-support-raw-string-literals;)");
  printf("\n");
  printf(
      R"(More reading material at - https: // docs.microsoft.com/en-us/cpp/c-language/c-string-literals?view=vs-2019)");
  printf("\n");
  printf(
      R"(More reading material at-https: // docs.microsoft.com/en-us/cpp/c-language/string-literal-concatenation?view=vs-2019)");
  printf("\n");
  /// Raw string.

    printf(R"(More reading material at - https://www.geeksforgeeks.org/const-qualifier-in-c/;)");
  printf("\n");
  
  
  return 0;
}

答案 6 :(得分:-2)

您正在寻找的是:

#include <stdio.h>
int main(void)
{
    printf("%s","Hello world\\nHello world");
    return 0;
}

这将产生以下输出:     Hello world \ n你好世界