在文档/规范中,它描述了如何在文本模式下将“\n”转换为特定于平台的行尾?

Where in the documentation/spec does it describe how '\n' is converted in text-mode to platform-specific line-endings?

提问人:Pod 提问时间:5/15/2023 最后编辑:Pod 更新时间:8/14/2023 访问量:100

问:

根据经验,我知道以下代码:

#include <iostream>

int main()
{
    std::cout << "Hello World!\n";
    return 0;
}

导致在不同的平台(例如 Linux:LF、Windows:CRLF)上打印不同的行尾,如果我想要特定行为,我有时必须将计数切换到二进制模式。同样,我知道,对于我自己打开的文件流,我必须小心地为我想要的行结束行为指定文本或二进制模式。

但是,我正在努力找到这种将 \n 转换为 CRLF 的行为实际上在哪里被记录下来!

我查看了C++规范(特别是 C++98 到 22)和各种在线参考(例如 cppreference.com),但找不到哪个类/库例程负责*实际将 转换为特定于平台的行尾'。(另外,不要问 ChaptGPT,它很高兴地从规范中编造不存在的引号)\n

或者换一种说法:C++ 的文本模式和二进制模式流的行为在哪里指定?

如果在C++规范中找不到它,那么问题是:它是从C继承的行为吗?如果是这样,它在哪里定义?

或者这是 C 从它运行的平台上继承的东西?

C++ 语言律师 换行符 std 行尾

评论

1赞 You 5/15/2023
这是(IIUC)C++从C继承的东西之一,所以在这方面这可能是一个c问题?此外,cppreference 只有一个注释来解释这一点,因此甚至可能没有任何规范性的东西;当然,实际的转换没有指定,因为它依赖于平台,并且发生在任何操作系统 API 之后。
0赞 Pod 5/15/2023
我也看过 C 规范,也找不到它。这只是一个超过 30+ 年的遗传行为案例,没有人费心去官方写下来?!
1赞 DevSolar 5/15/2023
@Pod:这类问题的答案基本上总是“不”。;-)关于流和刺痛的一些事情只在输入/输出 (stdio.h) 和字符串处理 (string.h) 的介绍章节中提到过,这让我自己错过了其中的一些内容。发生。;-)
1赞 BoP 5/15/2023
有些平台甚至不使用特定的行尾。例如,IBM 大型机使用字符串存储字符计数,并删除 .(可能在设计 C 之前就这样做了:-)'\n'
0赞 n. m. could be an AI 5/15/2023
“哪个特定的 API 在 C++ stdlib 中执行此操作” 不清楚您的意思。每个从文件读取或写入文件的函数最终都会这样做。如果您必须知道它是如何完成的(例如,他们调用哪个最低级别的函数来执行转换),则需要阅读 C++ 和/或 C 标准库实现的源代码。别无他法。

答:

4赞 DevSolar 5/15/2023 #1

来自 C 标准,7.21.2 Streams,强调我的:

文本流是组成行的有序字符序列,每行由零个或多个字符以及一个终止换行符组成。最后一行是否需要终止换行符是实现定义的。可能需要在输入和输出上添加、更改或删除字符,以符合在宿主环境中表示文本的不同约定。 因此,流中的字符与外部表示中的字符之间不需要一对一的对应关系。只有在以下情况下,从文本流中读入的数据才能与之前写出到该流的数据进行比较:数据仅由打印字符和控制字符水平制表符和换行符组成;换行符前面没有空格字符;最后一个字符是换行符。 读入时,在换行符之前写出的空格字符是否由实现定义。

二进制流是可以透明地记录内部数据的有序字符序列。在相同的实现下,从二进制流读入的数据应与之前写入该流的数据相等。但是,这样的流可能具有实现定义的 null 字符数,这些 null 字符附加到流的末尾。

C++基本上继承了这个定义。

参考您的问题的编辑:

如果找不到文档,那么替代答案是了解哪个特定 API 在 C++ stdlib、C stdlib 或各种操作系统平台中执行此操作。

您正在寻找的“API”是以文本模式打开流

您编写 或 ,库实现将执行任何必要的转换(可能不限于行尾)。printf( "Hello Bob!\n" )std::cout << "Hello Bob!\n"

评论

0赞 Pod 5/17/2023
虽然 C 规范中的引号在某种意义上适用,但他们在说“任何事情都可能发生!我想知道文本堆栈的哪个特定部分实际上说“我将交换 \n 为平台适当的行尾”。这种行为似乎主要是基于一些早期实现的行为,所有编译器编写者之间达成了某种“非正式协议”?例如,早期的 MSVC 转换为 CRLF,因为他们认为这是最有用的东西,所以 gcc 在移植到 Windows 时也效仿了?
0赞 DevSolar 5/17/2023
@Pod 该标准确实规定了 C 实现(编译器/库)需要并允许什么被视为“符合”,也就是“未损坏”。在这样做的同时,它非常小心地不侵犯平台/CPU 细节,因此合规的实现可以存在于广泛的平台上。如果一个平台有一个特定的约定,即什么可以考虑“行尾”(LF?铬?CR/LF?低频/低温?RS?我们?空字节?...),上面的“文本模式可以做转换”的规范允许实现在 C 空格 () 和平台所做的任何事情之间进行转换。\n
0赞 DevSolar 5/17/2023
(CTD.)也就是说,标准所谓的“外部表示”不在C标准的范围或权限范围内。它属于“实现定义”和“特定于实现”行为的广泛领域。请注意,这可能远远超出了行尾。