仅使用ISO 646在C99中写入换行符是否需要三角图?

仅使用ISO 646在C99中写入换行符是否需要三角图?,c,newline,stdio,trigraphs,C,Newline,Stdio,Trigraphs,假设您正在ISO 646的不变集合中编写(可移植)C99代码。这意味着不能直接写入\(反斜杠、反索利多士,不管你怎么称呼它)。例如,可以选择编写Hello World程序: %:include <stdio.h> %:include <stdlib.h> int main() <% fputs("Hello World!??/n", stdout); return EXIT_SUCCESS; %> %:包括 %:包括 int main()

假设您正在ISO 646的不变集合中编写(可移植)C99代码。这意味着不能直接写入
\
(反斜杠、反索利多士,不管你怎么称呼它)。例如,可以选择编写Hello World程序:

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

int main()
<%
    fputs("Hello World!??/n", stdout);
    return EXIT_SUCCESS;
%>
%:包括
%:包括
int main()
但是,除了有向图之外,我还使用了
??/
三向图来编写
\
字符

鉴于我以上的假设,是否有可能

  • 在字符串中包含
    '\n'
    字符(在
    函数中转换为换行符),而不使用三角图,或
  • 在不使用
    '\n'
    字符的情况下向
    文件*
    写入换行符

  • 是的,当然有可能

    fputc(0x0A, file);
    
    你的前提是:

    假设您正在ISO 646的不变集合中编写(可移植)C99代码。这意味着\(反斜杠,反索里达,不管你怎么称呼它)不能直接写入

    这是值得怀疑的。C99定义“源”和“执行”字符集,并要求两者都包含反斜杠字符的表示形式(C99 5.2.1)。我所能想象的像您所描述的那样努力的唯一原因是,尝试生成不需要在机器之间移动时进行字符集转码的源代码。然而,在这种情况下,选择ISO 646作为公共基线是很奇怪的。与使用与ISO-8859系列字符集不一致的ISO 646变体的EBCDIC计算机相比,您更可能遇到EBCDIC计算机。(如果您可以假设ISO 8859,那么反斜杠并不存在问题。)

    然而,如果您坚持在编写C源代码时不使用文本反斜杠字符,那么该字符的三角图就是这样做的方法。这就是发明三角图的目的。在字符常量和字符串文本中,您不能用任何其他内容替换
    \n
    或其trigraph等价物
    ??/n
    ,因为它取决于代码的映射方式。特别是,假设它映射到换行字符(然而,它包括在ISO 646的不变字符中)是不安全的

    更新:

    你特别问是否有可能

    在字符串中包含“\n”字符(在函数中转换为换行符),而不使用三角图,或


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

    你还问是否有可能

    是否在不使用“\n”字符的情况下向文件*写入换行符

    这完全取决于你的意思。如果要编写其代码在执行字符集中已知的字符,则可以编写具有该数值的数值常量。特别是,如果要使用编码值
    0xa
    (在执行字符集中)写入字符,则可以这样做。例如,你可以

    fputc(0xa, my_file);
    
    但这并不一定会产生与之相当的结果


    简而言之,是的,对于你想做的事情,你必须使用这个三角图

    即使有一个用于
    \
    的有向图,它在字符串文本中也是无用的,因为有向图必须是标记,它们被标记器识别,而trigraph是预处理的,因此仍然在字符串文本中工作等等


    还在想为什么今天会有人用这种方式编码源…:o

    对于
    stdout
    您可以使用
    put(“”
    )来输出换行符。或者将原始程序中的
    fput
    替换为
    put
    ,并删除
    \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中。维基百科有一个颜色编码表,颜色之间的对比度几乎不足以让我说出是什么。)

  • 否。
    \n
    (或其trigraph等价物)是换行符的可移植表示形式
  • 不可以。您必须以某种方式表示文字换行符,
    \n
    (或它的trigraph等价物)是唯一可移植的表示形式
  • 找到使用三角图或有向图的C源代码是非常罕见的!一些编译器(例如GNU gcc)需要命令行选项来启用Trigraph的使用,并假设它们是无意中使用的,如果在源代码中遇到它们,就会发出警告


    编辑:我忘记了
    put(“”)
    。这是一种偷偷摸摸的方法,但只适用于
    stdout

    我不确定我是否理解。您的字符集没有反斜杠,但您不想使用其三角图写入反斜杠?@zneak:这是不可能的,因为标准要求这些字符存在。(三角图是最多余的功能,至少从20年前开始)。@zneak我唯一需要使用三角图的地方(与有向图非常不同,因为它们是在不同的阶段翻译的)是写我唯一需要的反斜杠,也就是换行。感觉有点不对。转义序列没有“翻译”
    fprintf(stderr, "Hello, world!%c", gimme_a_newline());