C语言 如何在C中显式打印特殊字符?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29477345/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to print special characters explicitly in C?
提问by Jessie
When I use below code:
当我使用以下代码时:
#include <stdio.h>
int main(void)
{
printf("%s","Hello world\nHello world");
return 0;
}
it prints as:
它打印为:
Hello world
Hello world
How can I prevent this and print it as raw string literal in C? I mean it should be displayed as it is in terminal window like below:
如何防止这种情况并将其打印为 C 中的原始字符串文字?我的意思是它应该在终端窗口中显示,如下所示:
Hello world\nHello world
I know I can achieve this by using backslash for printf but is there any other C function or way to do this without backslashing? It would be helpful when reading files.
我知道我可以通过对 printf 使用反斜杠来实现这一点,但是有没有其他 C 函数或方法可以在不使用反斜杠的情况下做到这一点?在阅读文件时会很有帮助。
采纳答案by zwol
There is no built-in mechanism to do this. You have to do it manually, character-by-character. However, the functions in ctype.hmay help. Specifically, in the "C" locale, the function isprintis guaranteed to be true for all of the graphic characters in the basic execution character set, which is effectively the same as all the graphic characters in 7-bit ASCII, plus space; and it is guaranteed notto be true for all the controlcharacters in 7-bit ASCII, which includes tab, carriage return, etc.
没有内置机制可以做到这一点。您必须逐个字符地手动执行此操作。但是,中的功能ctype.h可能会有所帮助。具体来说,在“C”语言环境中,对于基本执行字符集中的isprint所有图形字符,该函数保证为真,这与 7 位 ASCII 中的所有图形字符有效相同,加空格;并且对于7 位 ASCII 中的所有控制字符(包括制表符、回车符等),保证不为真。
Here is a sketch:
这是一个草图:
#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;
}
This does not escape 'nor ", but it does escape \, and it is straightforward to extend that if you need it to.
这不逃'也不是",但它确实逃逸\,这是简单的扩展,如果你需要它。
Printing \nfor U+000A, \rfor U+000D, etc. is left as an exercise. Dealing with characters outside the basic execution character set (e.g. UTF-8 encoding of U+0080 through U+10FFFF) is also left as an exercise.
\nU+000A、\rU+000D 等的打印留作练习。处理基本执行字符集之外的字符(例如 U+0080 到 U+10FFFF 的 UTF-8 编码)也留作练习。
This program contains two things which are not necessary with a fully standards-compliant C library, but in my experience have been necessary on real operating systems. They are marked with (1)and (2).
这个程序包含两个完全符合标准的 C 库不需要的东西,但根据我的经验,在真实的操作系统上是必需的。它们用(1)和标记(2)。
1) This explicitly sets the 'locale' configuration the way it is supposedto be set by default.
1)这明确地将它的“区域”的配置方式应该到默认设置。
2) The value returned from getcharis an int. It is supposedto be either a number in the range representable by unsigned char(normally 0-255 inclusive), or the special value EOF(which is notin the range representable by unsigned char). However, buggy C libraries have been known to return negative numbers for characters with their highest bit set. If that happens, the printfwill print (for instance) \xffffffa1when it should've printed \xa1. Casting xto unsigned charand then back to unsigned intcorrects this.
2) 返回的值getchar是一个int。它应该是可表示的范围内的数字unsigned char(通常包括 0-255),或特殊值EOF(不在可表示的范围内unsigned char)。但是,众所周知,有缺陷的 C 库会为设置了最高位的字符返回负数。如果发生这种情况,printf将\xffffffa1在它应该打印时打印(例如)\xa1。投射x到unsigned char然后返回unsigned int纠正了这一点。
回答by yellowantphil
Something like this might be what you want. Run myprint(c)to print the character C or a printable representation of it:
像这样的东西可能是你想要的。运行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
}
If you're using Windows, I think all your newlines will be CRLF (carriage return, linefeed) so they'll print as 0d\nthe way I wrote that function.
如果您使用的是 Windows,我认为您的所有换行符都将是 CRLF(回车、换行),因此它们将0d\n按照我编写该函数的方式进行打印。
回答by John Bode
If I understand the question, if you have a string containing control characters like newline, tab, backspace, etc., you want to print a text representation of those characters, rather than interpret them as control characters.
如果我理解这个问题,如果您有一个包含换行符、制表符、退格符等控制字符的字符串,您希望打印这些字符的文本表示,而不是将它们解释为控制字符。
Unfortunately, there's no built-in printfconversion specifier that will do that for you. You'll have to walk through the string character by character, test each one to see if it's a control character, and write some text equivalent for it.
不幸的是,没有内置的printf转换说明符可以为您做到这一点。您必须逐个字符地遍历字符串,测试每个字符串以查看它是否是控制字符,并为其编写一些等效的文本。
Here's a quick, lightly tested example:
这是一个快速、经过简单测试的示例:
#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' );
回答by PADYMKO
Thank you the user @chunkfor contributing to the improvement this answer.
感谢用户@chunk为改进此答案做出的贡献。
Why did not you write general-purpose solution? It would keep you from many problems in the future.
你为什么不写通用解决方案?它会让你在未来远离许多问题。
char *
str_escape(char str[])
{
char chr[3];
char *buffer = malloc(sizeof(char));
unsigned int len = 1, blk_size;
while (*str != '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"));
}
') {
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;
}
How it work!
它是如何工作的!
\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
Output
输出
$ 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.
This solution based on an information from the Wikipedia https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequencesand the answers other users of the stackoverflow.com.
此解决方案基于来自维基百科https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences的信息 以及 stackoverflow.com 的其他用户的答案。
Testing environment
测试环境
#include <stdio.h>
int main(void)
{
printf("%s","Hello world\nHello world");
return 0;
}
回答by Vidya
Just use,putchar(specialCharName). It displays the entered special character.
只需使用,putchar(specialCharName)。它显示输入的特殊字符。
回答by Ivo Valchev
What you're looking for is this:
你要找的是这个:
##代码##This would produce the following output: Hello world\nHello world
这将产生以下输出:Hello world\nHello world

