【问题标题】:How do you overlap text in C terminal如何在 C 终端中重叠文本
【发布时间】:2017-09-12 15:36:40
【问题描述】:

我的 C 编程书中的一个训练练习如下所示:(翻译自瑞典语)

如果您使用书写/打字终端,有时您会像普通打字机一样,通过退后一行并在单词下方写下 _ 来为单词添加下划线。编写一个程序,将字符串写入变量s 下划线。

我的尝试如下所示:

#include <stdio.h>

int main(void) {
  char *s;
  printf("input: ");
  scanf("%ms", &s);
  for (int i=0; s[i] != '\0'; i++) {
    printf("%c\b_", s[i]);
  }
  printf("\n");
  return 0;
}

这不起作用,我希望终端输出是:

$> gcc -Wall -std=c99 file.c  
$> ./file.c  
input: test  
test //underlined
$>

但我得到的是:

$> gcc -Wall -std=c99 file.c  
$> ./file.c  
input: test  
____  
$> 

有人知道怎么做吗?还是这本书有问题?

【问题讨论】:

  • 了解ANSI escape codes。
  • 另请阅读utf8everywhere.org
  • 如果我的解释正确,您希望从字面上叠加两个字符 - 所以让单个终端单元格同时显示字母字符和下划线,以创建带下划线字符的印象。 Afaik,在大多数 现代 终端上,这是不可能的(可能有一些特定于终端的 hackiness)。虽然\b 是非破坏性的,但打印一个新字符被视为破坏性的。但是,您可以打印带有下划线的 unicode 字符,但您需要一个支持打印 unicode 的终端。
  • 如果您通过less 管道它也可以工作(因为传统的寻呼机必须能够通过nroff 显示传统的手册页,传统上使用过度标记,因为它是用于电传打字机的!)

标签: c terminal


【解决方案1】:

遗憾的是,我还没有找到一种方法来允许一个字符在另一个字符上的字面呈现(我认为现代终端不可能做到这一点,但我很高兴被证明是错误的,因为 Wumpus Q. Wumbley 已经做到了通过less 的管道允许这一点。不过,我没有时间了解它在less 中的工作方式/原因)。

我想提出一个解决方法 - 有一种方法可以使用 ANSI 代码 \033[4m 更直接地启用下划线。

修改你的代码:

#include <stdio.h>

int main()
{
  char *s;

  printf("input: ");
  scanf("%ms", &s);
  printf("\033[4m"); // Enable underlining
  printf("%s", s); // Print your string
  printf("\033[0m"); // Reset text attributes (disable underlining)
  printf("\n");
  return 0;
}

您可以在维基百科的 CSI 代码部分的 SGR 表中找到其他 ANSI 图形设置,here

\033 指定它是终端转义码,\e[ 的组合指定它是终端控制信号,然后 &lt;number&gt;m 指定我们正在执行“SGR”、“选择图形再现” ”命令,参数编号4对应效果“下划线:单”。 0 对应于重置。

我欢迎任何更正,因为我对 ANSI 代码格式了解不多。


我刚刚浏览了less 源,我怀疑它正在将_\ba 之类的序列转换为UTF 下划线字符-但我还没有完全了解它。

【讨论】:

  • 据我所知,标准中没有规定\e 是一个有效的字符常量;这必须取决于实现。它对我来说似乎在 gcc 中有效,但会生成编译器警告:“警告:非 ISO 标准转义序列,'\e'”。通常的转义序列是\x1b\033,它们分别是 ESC 字符的 ASCII 十六进制和八进制值。
  • @DavidBowling 感谢您的更正 - 我已经编辑了答案。
猜你喜欢
  • 1970-01-01
  • 2021-10-05
  • 2012-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 2017-10-28
相关资源
最近更新 更多