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

当我使用下面的代码时:

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

它打印为:

  Hello world Hello world 

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

 Hello world\nHello world 

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

没有内置机制来执行此操作。 你必须逐个字符地手动完成。 但是, ctype.h的函数可能会有所帮助。 具体来说,在“C”语言环境中,对于基本执行字符集中的所有图形字符,函数isprint保证为true,实际上与7位ASCII中的所有图形字符加空格相同; 并且保证7位ASCII中的所有控制字符都不成立,包括制表符,回车符等。

这是一个草图:

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

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

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

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

1)这显式地将’locale’配置设置为默认设置的方式。

2) getchar返回的值是一个int 。 它应该是可由unsigned char (通常为0-255)表示的范围内的数字,或特殊值EOF不在 unsigned char表示的范围内)。 但是,已知有错误的C库为具有最高位设置的字符返回负数。 如果发生这种情况, printf将打印(例如) \xffffffa1 ,它应该打印\xa1 。 将xunsigned char ,然后返回unsigned int更正此问题。

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

 #include  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

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

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

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

 #include  #include  #include  ... 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' ); 

感谢用户@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. 

您正在寻找的是:

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

这将产生以下输出:Hello world \ nHello world