如何在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
。 将x
为unsigned 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