在C++中,如何将ASCII艺术打印到控制台?

8

假设你想打印出一个很棒的 ASCII 艺术图像,但不想逐行使用 cout 来实现,那该怎么办呢?


2
自从C++11以来,您可以使用原始字符串字面值。请参见https://en.cppreference.com/w/cpp/language/string_literal,以获取示例,请参见https://dev59.com/YkvSa4cB1Zd3GeqPgbTb#34737663。 - Jonas Stein
4个回答

22

相邻的字符串字面量会被拼接在一起,所以你可以这样做:

cout << " _______________________ _______ _          _______         _______ _______  _______ _       _______         \n"
        "(  ____ \__   __/  ___  )  ____ \ \    /\  (  ___  )\     /|  ____ \  ____ )(  ____ \ \     (  ___  )\     /|\n"
        "| (    \/  ) (  | (   ) | (    \/  \  / /  | (   ) | )   ( | (    \/ (    )|| (    \/ (     | (   ) | )   ( |\n"
        "| (_____   | |  | (___) | |     |  (_/ /   | |   | | |   | | (__   | (____)|| (__   | |     | |   | | | _ | |\n"
        "(_____  )  | |  |  ___  | |     |   _ (    | |   | | (   ) )  __)  |     __)|  __)  | |     | |   | | |( )| |\n"
        "      ) |  | |  | (   ) | |     |  ( \ \   | |   | |\ \_/ /| (     | (\ (   | (     | |     | |   | | || || |\n"
        "/\____) |  | |  | )   ( | (____/\  /  \ \  | (___) | \   / | (____/\ ) \ \__| )     | (____/\ (___) | () () |\n"
        "\_______)  )_(  |/     \|_______/_/    \/  (_______)  \_/  (_______//   \__/|/      (_______/_______)_______)\n";

或者更准确地说,也许是:

cout << "                              .::/-                                                                                                                                                             \n"
        "                              .+++/                                                                                                                                                             \n"
        "                   `.::`       /+++.                                                                                                                                                            \n"
        "                  -////.      :+++-                                                                                                                                                             \n"
        "                    .////-`    .+++/`                                                                                                                                                           \n"
        "                    `:///:`   `/++/.                                                                                                                                                            \n"
        "            ..`        -////.   -+++:                                                                                                                                                           \n"
        "           :+++:-`      .////:` ./++/`                                                                                                                                                          \n"
        "          `-/+++++/-.    `:////.`:++/.                                                                                                                                                          \n"
        "             `.:/++++/:.`  -////..:--`                                                                                                                                                          \n"
        "                 .-/+++++/-..::.`                                                                                                                                                               \n"
        "       `:::-..``    `.:/++++-                                                                                                                                                                   \n"
        "       -++++++///:--.```.-/-                                                                                                                                                                    \n"
        "        `.--:///++++++//::.                                                                                                                                                                     \n"
        "`--.          ``..-::///+/``---                                                 -+-                                                             ./oso- /++:                                     \n"
        "-oo+  -::::----....````... `ooo                  :s-                            /mo                                                            -dmmhy:`hmmo                                     \n"
        "-oo+  /+++++++++++++++++/. `ooo                  om:                            /mo             ````     ```      ```    ``.``      ```  `.``  ommd`` `hmmo       ``.``    ```     ```     ```  \n"
        "-oo+  ...----::::////+++/` `ooo      `/ssyss+:`.ohmyoo` .+ssyss+-     -+syys+-  /mo    -o+.  .ohdmmdho- -hdd/   `sdds` :shmmmdy/`  .hddshdmmhoydmmmhy:`hmmo    .+hdmmmds- .ddd/   .ddh-   +ddh. \n"
        "-oo+  ```````````````````  `ooo     .yh-.``-/-  .sm/.` `/o-```-sd+  .sd+-..-++` /mo  .odo.  :dmmy+/smmm: +mmh-  /mmd- +mmh+:/smmy- .dmmdo/+s:`/ymmm++.`hmmo   .dmmh++smmd+`ommd` `ymmmy  .hmm+  \n"
        "-oo+  +oooooooooooooooooo- `ooo     -dy.         om:           -dy` +m/         /mo`+dy-   `smmy`  `smmy``smms`.hmm/ -dmd+---:hmmo`.dmm+       ommd   `hmmo   ommh.   ommh..ymm+ +mmdmm/ ommy.  \n"
        "-oo+  /++++++++++++++++++. `ooo      -oyhyyys/`  om:   `:osyyyyymy``sm-         /myhyhd:   `smms    +mmh` `dmm/smms  :dmmddddddddo`.dmm/       ommd   `hmmo   smmy`   /mmd. :dmd+dmy-ymd+hmd:   \n"
        "-oo+                       `ooo          ``.+do  om:   /do.    -dy``om:         /md/``od+` `ommh.  `ymmy`  :dmmmmy.  .hmd/`````.`  .dmm/       ommd    hmmo   +mmh-   smmy` `smmmmm- :dmmmmo    \n"
        "-oo+:::::::::::::::::::::::/ooo     -+:.```.od+  +mo.` /do.```.omy` .sd/.``.//` /mo    +dy. -ymmdysdmmh-    +mmmh-    :dmmyoosdd+` .dmm/       ommd    ommmso.`ymmdyshmmh:   .hmmm+   +mmmd`    \n"
        "-oooooooooooooooooooooooooooooo     ./syyyyyo:`  `:sys.`:syyyys+yo`  `:syyyyo:` :h/     :ys` `:shddhs/`     `ohy/      ./shddhy+-  .shh:       /hhy    `:syhs. `:oyhdhs/.     /hho`   `shh/     \n"

更明智的做法是使用endl。这与在每行后面仅使用"\n"略有不同,因为您还将刷新输出流。


这是来自patorjk.com生成器的"Epic"字体。 - John Feminella
3
这些示例由于包含转义序列而无法正常运行。每次看到“\”符号时,都是转义序列的开头,并且不会在控制台上显示任何内容。实际上,编译它们会收到警告。我正在努力弄清楚为什么这被选为最佳答案。 - Neil Roy
1
这些示例会出现“warning: unknown escape sequence: '_'”的警告,调整字体对答案没有任何有用的贡献。 - Jonas Stein

10

试试这样做:

cout << R"(place multiple lines
           of text here
           and it will display exactly
           as you have it between the two brackets,
           line feeds and all.)";

上面的代码还允许您使用像反斜杠\这样的字符而无需两个,它会显示所有内容并且不会识别控制码,例如\n等。非常方便。

这称为“字符串字面值”,在C++11中添加。您可以在此处找到有关命令的更多信息,特别是参考前缀“R”,该前缀用于原始字符:https://en.cppreference.com/w/cpp/language/string_literal


这在特定的版本中添加了吗? - DBrown
我真的不记得了。几年前我在Visual Studio中使用它,效果很好,所以你不应该有问题。 - Neil Roy
你知道你使用的是哪个版本的C++吗?我问这个问题是因为有很多基于v11 C++的项目,如果这个功能是在2011年之后的版本中添加的话,可能就无法使用了。据我所知,它看起来像是C11/C99的新增功能,但无法确认。 - DBrown
我进行了更多的搜索,最终找到了它。它被称为“字符串字面值”,并在C++11中添加。以下是一个页面,描述了您可以使用的更多详细信息。 https://en.cppreference.com/w/cpp/language/string_literal - Neil Roy
2
更具体地说,它是一个“原始字符串字面量”。仅称其为“字符串字面量”会让人感到困惑,因为"foobar"也是一个“字符串字面量”。 - HolyBlackCat
@HolyBlackCat 虽然这样称呼可以更清晰地表达,但在C++11中它的名称仅为“字符串字面值”。而且你可以使用不同类型,它并不是技术上所谓的“原始字符串字面值”,而是包含原始字符的“字符串字面值”。这可能看起来像是我在挑剔,但点击链接就可以很清楚地了解这一点,结合我的示例代码和链接,就不会有任何混淆。 - Neil Roy

2
其他人已经建议使用endl。虽然这不是(必要的)坏事,但使用endl会刷新流的缓冲区,并写入一个新行。与您获得的答案中所暗示的相反,使用endl根本不能帮助将换行符转换为平台通常用于表示行末的字符序列。使用newline保证与stream << "\n" << flush;完全等效。将换行符转换为"\r"、"\n"或"\r\n"或其他平台首选的字符是在不同级别上完成的,newline与此无关。
然而,它执行的flush可以(并且经常会)减慢I/O速度,有时甚至会非常明显。只要您只写入几行(例如几百个字符),这可能完全无关紧要。但如果您要写入大文件,则使用endl而不是"\n"很容易导致10倍的减速(实际上,我敢说很多人认为iostreams很慢的想法直接源于使用endl)。
这并不是说从来没有使用endl的理由。刷新确保已写入流的任何内容立即刷新出标准库的缓冲区并发送到操作系统。如果您想确保立即显示,endl可能很有用。同样,如果您正在进行日志记录,并且关键是您的日志始终反映程序的最新已知状态,则endl可能非常有用,以确保您所写的内容真正被记录,而不会在应用程序崩溃时/如果丢失在缓冲区中。
因此,endl有时是有意义的,但在使用它的95%的时间里,它可能真的不适合(例如,在回答这个问题的任何答案中都不太可能实现任何有用的东西)。

-1

这很简单,谢天谢地。只需在需要换行时使用 endl。

cout << stuff << endl
     << morestuff << endl
     << evenmorestuff << endl;

我想说我更喜欢使用endl,因为它应该可以在需要"\r\n"而不仅仅是"\n"的平台上工作。

2
虽然这是一个显而易见的答案,但如果经常这样做,通过这种方式打印许多行可能会成为 CPU 的负担。每次使用重载运算符 << 都会在其后隐藏一个函数调用,因此打印多行文本需要进行非常多的函数调用。 - mingos
是的,如果所有他要做的只是打印一些ASCII艺术品,那么这种方法可能会变得繁琐,但并不应该成为问题。另一种方法是将所有内容打包成一个大字符串,然后一次性输出。我有时不得不这样做,但大多数情况下,这种方法并不成问题。 - Player1st
你关于 std::endl 的评论很愚蠢。即使你在一个需要 \r\n 而不是 \n 作为本地行终止符的平台上,\n 仍然是 C 和 C++ 中的换行符,并且 I/O 库会为你转换它。(这是文本模式和二进制模式流之间的区别。)std::endl 比原始的 \n 稍微低效一些,因为它不必要地刷新了流。 - jamesdlin
你可能是对的,但是很多年前我确实遇到了一些问题。现在几乎所有使用'\n'的东西都没有问题。 - Player1st
1
请再次阅读问题。他特别询问如何在不逐行计数的情况下完成此操作。 - Neil Roy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接