| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2139 人关注过本帖
标题:控制台 I/O 和流 I/O 的区别
只看楼主 加入收藏
yiyue123
Rank: 2
等 级:论坛游民
威 望:1
帖 子:78
专家分:78
注 册:2018-6-18
结帖率:100%
收藏
 问题点数:0 回复次数:6 
控制台 I/O 和流 I/O 的区别
看了看微软的官方文档,对于控制台应用,它提供了相应的 I/O 函数 ReadConsole 和 WriteConsole。
根据文档的描述,ReadConsole 是直接从控制台缓冲区中读取字符,WriteConsole 直接将字符写入到控制台的输入缓冲区
看到这里,不禁联想到了 C 标准库提供的 stdio,和其中的 标准文件描述符 stdin,stdout, stderr。stdin,stdout 都是有它们自己的缓冲区的。
那么控制台的缓冲区和标准流的缓冲区之间有什么关系呢?

程序代码:
#include <Windows.h>
#include <tchar.h>
#include <stdio.h>

int main(void)
{
    HANDLE hStream;
    hStream = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD num_written;
    int ok;
    TCHAR out[] = TEXT("hello");
    ok = WriteConsole(hStream, out, wcslen(out), &num_written, NULL);
    if (!ok)
    {
        MessageBox(NULL, TEXT("failure"), TEXT("1"), MB_OK);
    }
    CloseHandle(hStream);
    ok = printf("World");

    char buffer[10];
    sprintf_s(buffer, 10, "%d", ok);
    MessageBoxA(NULL, buffer, "2", MB_OK)
    return 0;
}


这段代码编译并运行,可以在控制台上看到 Hello,但是看不到 World,而且 MessageBox 弹窗显示的值是 5,说明 printf 调用成功了。
个人理解: printf 成功的将输 World 写入到了输出缓冲,但是标准输出句柄已经被关闭,所以无法显示到屏幕

程序代码:
#include <Windows.h>
#include <tchar.h>
#include <stdio.h>

int main(void)
{
    HANDLE hStream;
    hStream = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD num_written;
    int ok;
    TCHAR out[] = TEXT("hello");
    ok = WriteConsole(hStream, out, wcslen(out), &num_written, NULL);
    if (!ok)
    {
        MessageBox(NULL, TEXT("failure"), TEXT("1"), MB_OK);
    }
    //CloseHandle(hStream);
    fclose(stdout);
    
    ok = WriteConsole(hStream, out, wcslen(out), &num_written, NULL);
    if (!ok)
    {
        MessageBox(NULL, TEXT("failure2"), TEXT("1"), MB_OK);
    }
    return 0;
}

这段代码会弹出窗口,显示 failure2。说明 第二次 WriteConsole 调用失败。

请问,控制台和流的缓冲区之间有什么样的关系?
搜索更多相关主题的帖子: 缓冲区 NULL out 控制台 TEXT 
2020-06-16 15:13
yiyue123
Rank: 2
等 级:论坛游民
威 望:1
帖 子:78
专家分:78
注 册:2018-6-18
收藏
得分:0 
嘛,也算自问自答吧,我找到答案了。
文件指针的层次高于文件句柄。
2020-06-17 12:43
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:0 
回复 2楼 yiyue123
听不懂你在说啥,你想问啥,
printf 等C语言提供的,是跨平台的,但它必然是基于各自平台本身提供的能力(比如 WriteConsole 等)。
2020-06-17 12:49
yiyue123
Rank: 2
等 级:论坛游民
威 望:1
帖 子:78
专家分:78
注 册:2018-6-18
收藏
得分:0 
回复 3楼 rjsp
确实,我在问这个问题的时候,思路比较混乱。
我想问的问题是,控制台输入缓冲区和标准流 stdin 的关系,不过我的表述可能不是太清楚。
后来查阅了微软的文档,它说,控制台输入缓冲区句柄就是个文件句柄,而文件指针之类的东西肯定是要依靠文件句柄的,
_open_osfhandle 函数可以打开一个和文件句柄相关联的文件标识符
https://docs.
而 _fdopen 函数可以打开一个文件标识符相应的文件指针,也就是流。
在这里我就弄清楚了,文件指针依靠底层的文件句柄,也就是你的回答。
用户的输入先到达控制台缓冲区,再到达流的缓冲区,最后被用户读取。
2020-06-17 13:29
ditg
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:16
帖 子:852
专家分:1937
注 册:2014-4-10
收藏
得分:0 
第一次open设备文件返回0,对应至任务数据结构的文件结构数组第一项

梦想拥有一台龙芯3A-4000
2020-06-17 14:50
八画小子
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:37
帖 子:709
专家分:2063
注 册:2010-11-11
收藏
得分:0 
一个是Windows API,另一个是C标准中的概念。如果你要细究,牵扯的东西有点多,不太好具体说。
2020-06-18 07:41
yiyue123
Rank: 2
等 级:论坛游民
威 望:1
帖 子:78
专家分:78
注 册:2018-6-18
收藏
得分:0 
确实如此,最好只用一个,这样太麻烦了
2020-06-18 10:01
快速回复:控制台 I/O 和流 I/O 的区别
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015431 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved