FILE的一个问题

博主揭示了Windows下不同IDE对控制台文件流处理的差异,重点在于VC6与VS2015中FILE结构的不同。解决方法涉及跨版本操作技巧和Solaris中FILE定义的挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这两天研究windows下,控制台窗口的输入输出,发现了一个问题,记录下来,希望对有需要的人有所帮助。

https://blog.youkuaiyun.com/dolphin98629/article/details/109846877

用_open_osfhandle,发现在VS 2017/2019不能用,又在vc6下测试了一下,发现能正常使用的,于是越来越好奇

找找原因,发现问题在FILE的定义里

VC6是这样定义的:

​
struct _iobuf {
        char *_ptr;
        int   _cnt;
        char *_base;
        int   _flag;
        int   _file;
        int   _charbuf;
        int   _bufsiz;
        char *_tmpfname;
        };
typedef struct _iobuf FILE;

_CRTIMP FILE _iob[];
​
#define stdin  (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])

VS2015是这样定义的

struct __crt_stdio_stream_data
{
	union
	{
		FILE  _public_file;
		char* _ptr;
	};

	char*            _base;
	int              _cnt;
	long             _flags;
	long             _file;
	int              _charbuf;
	int              _bufsiz;
	char*            _tmpfname;
	CRITICAL_SECTION _lock;
};

// FILE descriptors for stdin, stdout, and stderr
extern "C" __crt_stdio_stream_data _iob[_IOB_ENTRIES] =
{
    // ptr      _base,   _cnt, _flag,                                    _file, _charbuf, _bufsiz
    {  nullptr, nullptr, 0,    _IOALLOCATED | _IOREAD,                   0,     0,        0        }, // stdin
    {  nullptr, nullptr, 0,    _IOALLOCATED | _IOWRITE,                  1,     0,        0        }, // stdout
    {  nullptr, nullptr, 0,    _IOALLOCATED | _IOWRITE | _IOBUFFER_NONE, 2,     0,        0        }, // stderr
};

extern "C" FILE* __cdecl __acrt_iob_func(unsigned const id)
{
    return &_iob[id]._public_file;
}


#define stdout (__acrt_iob_func(1))
//明显iob里面存放的是__crt_stdio_stream_data,不知道为什么不用定义好的?

明显2015的FILE只存放了个指针,就不能用vc6那样直接

*stdout=*hf了

但是也不是不能直接修改,只需要简单的扩展一下就可以

*(__crt_stdio_stream_data *)stdput=*(__crt_stdio_stream_data *)hf;

这样整个结构就会复制成功,编译运行,正常。

 

再来吐槽一下solaris,这个号称也不错的系统,里面的FILE是这么定义的:

/*
Solaris 
*/
struct __FILE_TAG
{
#ifdef _STDIO_REVERSE
	unsigned char   *_ptr;
	int             _cnt;
#else
	int             _cnt;
	unsigned char   *_ptr;
#endif
	unsigned char   *_base;
	unsigned char   _flag;
	unsigned char   _file;
	/* UNIX System file descriptor */
	unsigned        __orientation : 2;
	unsigned        __ionolock : 1;
	unsigned        __seekable : 1;
	unsigned        __filler : 4;
};

WTF,file竟然只用了个char,单进程最多只能打开255个文件。。。。

不过这个问题也不是不能解决,

参见我的另一篇blog,https://blog.youkuaiyun.com/trublemaker/article/details/50535779

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值