仅使用 ISO 646 在 C99 中编写换行符是否需要三字母?

Are trigraphs required to write a newline character in C99 using only ISO 646?

假设您正在 ISO 646 的不变集中编写(可移植的)C99 代码。这意味着 \(反斜杠、反斜线,无论您如何命名)不能直接编写.例如,可以选择这样编写 Hello World 程序:

%:include <stdio.h>
%:include <stdlib.h>

int main()
<%
    fputs("Hello World!??/n", stdout);
    return EXIT_SUCCESS;
%>

但是,除了二合字母,我还使用了??/三字母来写\字符。

根据我上面的假设,是否可以

  1. 在字符串中包含 '\n' 字符(在 <stdio.h> 函数中转换为换行符)不使用 三字母组合,或者
  2. 不使用 '\n' 字符向 FILE * 写入换行符?

当然可以

fputc(0x0A, file);

你的前提:

Assume that you're writing (portable) C99 code in the invariant set of ISO 646. This means that the \ (backslash, reverse solidus, however you name it) can't be written directly.

有疑问。 C99 定义了 "source" 和 "execution" 字符集,并要求两者都包含反斜杠字符的表示形式 (C99 5.2.1)。对于您所描述的这种努力,我可以想象的唯一原因是尝试生成不需要在机器之间移动时进行字符集转码的源代码。然而,在那种情况下,选择 ISO 646 作为共同基准是很奇怪的。您更有可能 运行 进入 EBCDIC 机器,而不是使用与 ISO-8859 字符集系列不一致的 ISO 646 变体的机器。 (如果您可以假定 ISO 8859,那么反斜杠不会出现问题。)

尽管如此,如果您坚持不使用文字反斜杠字符来编写 C 源代码,那么该字符的三字母表就是这样做的方法。这就是发明三字母的目的。在字符常量和字符串文字中,您不能用其他任何东西替代 \n 或其等价的三字母 ??/n,因为它是依赖于实现的,代码是如何映射的。特别是,假设它映射到换行符(然而,它包含在 ISO 646 的不变字符中)是不安全的。

更新:

你具体问一下是否可以

include the '\n' character (which is translated to a newline in functions) in a string without the use of trigraphs, or

不,不可能,因为没有'\n'个字符。此外,这里似乎有点误解:字符或字符串文字中的 \n 表示执行字符集中的 一个 字符。因此,编译器负责该转换,而不是 stdio 函数。 stdio 函数的职责是通过编写旨在产生指定效果的字符或字符序列来处理输出中的该字符(“[m] 将活动位置移动到下一行的初始位置”)。

你也问是否可以

write a newline to a FILE * without using the '\n' character?

这完全取决于您的意思。如果你想写一个你知道其在执行字符集中的代码的字符,那么你可以写一个具有该数值的数字常量。特别是,如果你想写编码值为 0xa 的字符(在执行字符集中),那么你可以这样做。例如,您可以

fputc(0xa, my_file);

但这不一定会产生等同于

的结果
fputc('\n', my_file);

简短的回答是,是的,对于您想做的事情,您必须使用这个三字母。

即使 \ 的二合字母,它在 字符串文字 中也是无用的,因为二合字母必须是标记,它们被标记器识别,而三字母经过预处理,因此仍然可以在字符串文字等中使用。

仍然想知道为什么今天有人会这样编码源...:o

对于stdout你可以只使用puts("")来输出一个换行符。或者确实用 puts 替换原始程序中的 fputs 并删除 \n.

如果您想将换行符放入一个变量中以便用它做其他事情,我知道另一个免费提供给您的标准函数:

int gimme_a_newline(void)
{
  time_t t = time(0);
  return strchr(ctime(&t), 0)[-1];
}

然后你可以说

fprintf(stderr, "Hello, world!%c", gimme_a_newline());

(我希望我使用的所有字符都是 ISO646 或二合字母可访问的。我发现很难得到一个简单的列表,列出哪些 ASCII 字符不在 ISO646 中。维基百科有一个颜色编码的 table 颜色之间的对比度几乎不足以让我分辨出什么是什么。)

  1. 没有。 \n(或其等效的三字母)是换行符的可移植表示。
  2. 没有。您必须以某种方式表示字面换行符,而 \n (或其等价的三字母)是唯一可移植的表示形式。

很难找到使用三字母或二字母的 C 源代码!一些编译器(例如 GNU gcc)需要命令行选项来启用三字母的使用,并假定它们是无意中使用的,并在源代码中遇到它们时发出警告。

编辑:我忘了 puts("")。这是一种偷偷摸摸的方式,但只适用于 stdout.