如何在不将 LF 转换为 CR LF 的情况下将 C 输出到标准输出?

13

在Windows上,这个

#include <stdio.h>

int main() { 
    putc('A',stdout);
    putc('\r',stdout); 
    putc('\n',stdout);
}

输出

A<CR><CR><LF>

如何在不自动转换为CR LF的情况下仅将LF字符写入stdout?

我需要这样做是为了制作简单的套接字流读取器到stdout。我尝试使用来自CodeGear的bcc32,mingw,tinycc,所有结果都一样,将putc更改为putchar,fputc,fwrite也无济于事。

3个回答

14

MSVC 的解决方案如下:

#include <io.h>
#include <fcntl.h>
...
_setmode(1,_O_BINARY)

其他运行时环境可能提供C99解决方案或其他替代方式。编辑:我认为setmode([文件号],O_BINARY)起源于Borland Turbo C,其他编译器为MS-DOS和Windows模仿它。前缀 _ 是为了保持命名空间的清晰,并且在某些编译器上可能不存在。


但它不支持将NULL作为文件名传递,而且您开始使用的标准输出可能没有文件名。 - Random832
谢谢。它可以工作,即使在tinycc和mingw上没有包含io.h。在bcc32上必须包含io.h,然后将_setmode更改为setmode。 - Daniel Leung
从Windows 10开始(至少如此),这是不够的。控制台进行了自己的转换,应通过设置DISABLE_NEWLINE_AUTO_RETURN控制台模式单独禁用。(该常量定义在Windows 10 SDK中,但未在Windows 8 SDK中定义) - AnT stands with Russia
@AnT OP没有提到控制台。我假设stdout是一个管道或文件,因为在控制台上无法区分一行中的一个CR和两个CR。 - Random832

3
#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
#endif

#ifdef __BORLANDC__
#define _setmode setmode
#endif

#include <stdio.h>

static void binary_stdout(void) {
#ifdef _WIN32
    _setmode(_fileno(stdout), _O_BINARY);
#endif
}

int main(void) {
    binary_stdout();
    printf("\n");
    return 0;
}

3

文本文件会将 C 字符 '\n' 在输出时转换为本地行结尾,并在输入时将本地行结尾转换为单个 '\n'

要获得所需的结果,您需要将 stdout 改为二进制文件流。

可以在此处找到部分答案:这里。如果您有符合 C99 标准的库,则可以使用:

if (freopen(0, "wb", stdout) == 0)
    ...oops...operation failed...

将尝试将标准输出更改为二进制流。但是,在Windows上,“C99兼容库”可能会成为一个问题。通常,这是一种便携式(因为标准)的答案。可能有一个特定于Windows的函数来完成同样的工作。


@Ignacio:是的,谢谢 - 找到了...我们活着,学着,回答问题。 - Jonathan Leffler
@James:freopen()函数自Unix第7版起就在<stdio.h>中存在,但是在C99中,使用空指针作为文件名的行为是新的。C89标准对空指针没有任何说明。 - Jonathan Leffler

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