如何验证c++的标准输入输出是预先存在buffer中

dachuannnnn 2013-06-23 11:57:34
最近看c++ primer,想验证一下。
不要说重定向的例子啊
...全文
319 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2013-06-26
  • 打赏
  • 举报
回复
运行并调试一下,这个程序吧!
int main(){
    char c='x';
    while(c!=q){
    cin>>c;
    cout<<c;
    }
    cout<<endl;
    return ;  
}
mujiok2003 2013-06-25
  • 打赏
  • 举报
回复
引用 20 楼 getmonyinfo 的回复:
[quote=引用 19 楼 mujiok2003 的回复:] [quote=引用 18 楼 getmonyinfo 的回复:] [quote=引用 17 楼 mujiok2003 的回复:] [quote=引用 16 楼 getmonyinfo 的回复:]

#include<iostream>
#include <unistd.h>

int main ()
{
	std::cout << " world";
	write (1, "hello", 5);  //write函数不带缓冲
	std::cout <<  std::endl;
}

output:
hello world


write是系统API,不属于c/c++。[/quote] 是!不过这足以验证std::cout是带缓冲的了[/quote] 只能证明你的编译器(g++)的std::cout是带缓冲的。 [/quote] 哈哈,笑死我了,g++的std::cout, 不错的玩笑啊, 什么时候iso c++的std移民到g++了,你这俩星星级别是怎么偷来的[/quote] iso c++是标准, g++是实现。 你继续笑吧。
getmonyinfo 2013-06-25
  • 打赏
  • 举报
回复
引用 19 楼 mujiok2003 的回复:
[quote=引用 18 楼 getmonyinfo 的回复:] [quote=引用 17 楼 mujiok2003 的回复:] [quote=引用 16 楼 getmonyinfo 的回复:]

#include<iostream>
#include <unistd.h>

int main ()
{
	std::cout << " world";
	write (1, "hello", 5);  //write函数不带缓冲
	std::cout <<  std::endl;
}

output:
hello world


write是系统API,不属于c/c++。[/quote] 是!不过这足以验证std::cout是带缓冲的了[/quote] 只能证明你的编译器(g++)的std::cout是带缓冲的。 [/quote] 哈哈,笑死我了,g++的std::cout, 不错的玩笑啊, 什么时候iso c++的std移民到g++了,你这俩星星级别是怎么偷来的
mujiok2003 2013-06-25
  • 打赏
  • 举报
回复
引用 18 楼 getmonyinfo 的回复:
[quote=引用 17 楼 mujiok2003 的回复:] [quote=引用 16 楼 getmonyinfo 的回复:]

#include<iostream>
#include <unistd.h>

int main ()
{
	std::cout << " world";
	write (1, "hello", 5);  //write函数不带缓冲
	std::cout <<  std::endl;
}

output:
hello world


write是系统API,不属于c/c++。[/quote] 是!不过这足以验证std::cout是带缓冲的了[/quote] 只能证明你的编译器(g++)的std::cout是带缓冲的。
getmonyinfo 2013-06-25
  • 打赏
  • 举报
回复
引用 17 楼 mujiok2003 的回复:
[quote=引用 16 楼 getmonyinfo 的回复:]

#include<iostream>
#include <unistd.h>

int main ()
{
	std::cout << " world";
	write (1, "hello", 5);  //write函数不带缓冲
	std::cout <<  std::endl;
}

output:
hello world


write是系统API,不属于c/c++。[/quote] 是!不过这足以验证std::cout是带缓冲的了
mujiok2003 2013-06-25
  • 打赏
  • 举报
回复
引用 16 楼 getmonyinfo 的回复:

#include<iostream>
#include <unistd.h>

int main ()
{
	std::cout << " world";
	write (1, "hello", 5);  //write函数不带缓冲
	std::cout <<  std::endl;
}

output:
hello world


write是系统API,不属于c/c++。
getmonyinfo 2013-06-25
  • 打赏
  • 举报
回复

#include<iostream>
#include <unistd.h>

int main ()
{
	std::cout << " world";
	write (1, "hello", 5);  //write函数不带缓冲
	std::cout <<  std::endl;
}

output:
hello world


www_adintr_com 2013-06-25
  • 打赏
  • 举报
回复
引用 13 楼 taodm 的回复:
不要试图去验证这些知识。没用处。 有用的东西还学不过来呢。
我觉得世界上所有的知识都是有用的, 没有无用的东西. 如果大家都只去研究那些热门的东西, 这个世界也太无趣了.
www_adintr_com 2013-06-25
  • 打赏
  • 举报
回复
引用 12 楼 dachuannnnn 的回复:
[quote=引用 10 楼 adlay 的回复:]

#include <Windows.h>
#include <stdio.h>

int main()
{
	printf("Start\n");
	Sleep(1000);
	printf("H");
	Sleep(1000 * 10);
	printf("\n");
}

然后用秒表掐时间, 看是输出 Start 后 1 秒出现的 H 还是 11 秒后才出现的.
这个方法 可靠吗。。[/quote] 当然, 除非你连 1 秒和 10 秒的区别都感觉不出来.
mujiok2003 2013-06-25
  • 打赏
  • 举报
回复
引用 楼主 dachuannnnn 的回复:
最近看c++ primer,想验证一下。 不要说重定向的例子啊
1. 如果标准输入、输入流不与交互式设备关联,则是完全缓冲的。 2. 如果标准输入、输入流与交互式设备关联, 是否缓冲或者如何缓冲则由具体实现决定。 看看书上是不是这么说的。
mujiok2003 2013-06-25
  • 打赏
  • 举报
回复
引用 24 楼 getmonyinfo 的回复:
[quote=引用 23 楼 mujiok2003 的回复:] [quote=引用 22 楼 getmonyinfo 的回复:] 标准是标准,编译器是编译器。c++标准只有一个,但c++编译器可以有无数个。编译器的工作是把符合标准的代码翻译成对应的汇编指令。我的g++只会翻译我的代码,不会实现iso c++标准,也不会把在标准库中的cout实现到g++编译器中
回到楼主的问题: 不过你的实例证明不了std::cout是带缓冲的,最多的也就是你的实现是带缓冲的。不是为了跟你抬杠。 另外: 编译结果是机器码,而不是汇编码。 [/quote] 好吧, 我只是就问题论问题,不知是不是我说的太冲了, 才让你有感觉要抬扛的想法。 回到问题,我要说的是我的程序是可以证明std::cout是带缓冲的。write函数在用户空间内是没有缓冲区的,所以不管给他什么内容它立马写到标准输出上。std::cout为了效率考虑,提供一个buffer,而这个buffer的行为在交互模式下需要用endl冲刷,所以我的程序输出的是hello world, 如果std::cout 没有缓冲,岂不是要输出worldhello。 另外你说的“最多的也就是你的实现是带缓冲的”,不知你要说的是什么。gcc编译器系列是对标准支持最好的, 如果g++都不能证明std::cout是带缓冲的,那么我也可以认为任何编译器都不能证明std::cout带缓冲。[/quote] 1. 讨论C++,不该用实现相关的代码来得得出结论,因为这样往往不可靠。 2. 就本问题而言,我认为是这样的: 2.1 The objectcoutcontrols output to a stream buffer associated with the object stdout, declared in <cstdio>(27.8.2). 2.2 If stdout is known to not refer to an interactive device, the stream is fully buffered. Otherwise, it is library-dependent whether the stream is line buffered or not buffered by default.
getmonyinfo 2013-06-25
  • 打赏
  • 举报
回复
引用 23 楼 mujiok2003 的回复:
[quote=引用 22 楼 getmonyinfo 的回复:] 标准是标准,编译器是编译器。c++标准只有一个,但c++编译器可以有无数个。编译器的工作是把符合标准的代码翻译成对应的汇编指令。我的g++只会翻译我的代码,不会实现iso c++标准,也不会把在标准库中的cout实现到g++编译器中
回到楼主的问题: 不过你的实例证明不了std::cout是带缓冲的,最多的也就是你的实现是带缓冲的。不是为了跟你抬杠。 另外: 编译结果是机器码,而不是汇编码。 [/quote] 好吧, 我只是就问题论问题,不知是不是我说的太冲了, 才让你有感觉要抬扛的想法。 回到问题,我要说的是我的程序是可以证明std::cout是带缓冲的。write函数在用户空间内是没有缓冲区的,所以不管给他什么内容它立马写到标准输出上。std::cout为了效率考虑,提供一个buffer,而这个buffer的行为在交互模式下需要用endl冲刷,所以我的程序输出的是hello world, 如果std::cout 没有缓冲,岂不是要输出worldhello。 另外你说的“最多的也就是你的实现是带缓冲的”,不知你要说的是什么。gcc编译器系列是对标准支持最好的, 如果g++都不能证明std::cout是带缓冲的,那么我也可以认为任何编译器都不能证明std::cout带缓冲。
mujiok2003 2013-06-25
  • 打赏
  • 举报
回复
引用 22 楼 getmonyinfo 的回复:
标准是标准,编译器是编译器。c++标准只有一个,但c++编译器可以有无数个。编译器的工作是把符合标准的代码翻译成对应的汇编指令。我的g++只会翻译我的代码,不会实现iso c++标准,也不会把在标准库中的cout实现到g++编译器中
回到楼主的问题: 不过你的实例证明不了std::cout是带缓冲的,最多的也就是你的实现是带缓冲的。不是为了跟你抬杠。 另外: 编译结果是机器码,而不是汇编码。
getmonyinfo 2013-06-25
  • 打赏
  • 举报
回复
引用 21 楼 mujiok2003 的回复:
[quote=引用 20 楼 getmonyinfo 的回复:] [quote=引用 19 楼 mujiok2003 的回复:] [quote=引用 18 楼 getmonyinfo 的回复:] [quote=引用 17 楼 mujiok2003 的回复:] [quote=引用 16 楼 getmonyinfo 的回复:]

#include<iostream>
#include <unistd.h>

int main ()
{
	std::cout << " world";
	write (1, "hello", 5);  //write函数不带缓冲
	std::cout <<  std::endl;
}

output:
hello world


write是系统API,不属于c/c++。[/quote] 是!不过这足以验证std::cout是带缓冲的了[/quote] 只能证明你的编译器(g++)的std::cout是带缓冲的。 [/quote] 哈哈,笑死我了,g++的std::cout, 不错的玩笑啊, 什么时候iso c++的std移民到g++了,你这俩星星级别是怎么偷来的[/quote] iso c++是标准, g++是实现。 你继续笑吧。 [/quote] 标准是标准,编译器是编译器。c++标准只有一个,但c++编译器可以有无数个。编译器的工作是把符合标准的代码翻译成对应的汇编指令。我的g++只会翻译我的代码,不会实现iso c++标准,也不会把在标准库中的cout实现到g++编译器中
www_adintr_com 2013-06-24
  • 打赏
  • 举报
回复

#include <Windows.h>
#include <stdio.h>

int main()
{
	printf("Start\n");
	Sleep(1000);
	printf("H");
	Sleep(1000 * 10);
	printf("\n");
}

然后用秒表掐时间, 看是输出 Start 后 1 秒出现的 H 还是 11 秒后才出现的.
mujiok2003 2013-06-24
  • 打赏
  • 举报
回复
调试一下,以vc++ 2012为例.

std::streambuf* pcinbuf = std::cin.rdbuf();
double v;
std::cin >> v; //enter: 7.8 and more
std::streambuf* pcoutbuf = std::cout.rdbuf();
std::cout << "hello";
return 0;


执行到return 0;察看pcinbuf和pcoutbuf




这里只说明VC2012的实现而已,其它编译未必如此.不过要求证其它编译器是如何实现的,方法类似.
  • 打赏
  • 举报
回复
先cout输出 再调用
VOID WINAPI ExitProcess(
  __in  UINT uExitCode
);
lm_whales 2013-06-24
  • 打赏
  • 举报
回复
写个程序,调试之看汇编源码或者二进制代码。
dachuannnnn 2013-06-24
  • 打赏
  • 举报
回复
引用 4 楼 It_way 的回复:
ISO 标准的 C/C++ 是带缓冲的,所有对上层IO的读写对象 都是 缓冲区 当遇到以下几种情况 会 将 缓冲区 的 内容 真正的写入 1、遇到换行 2、缓冲区满了 3、手动调用 fflush ...
对,我知道这些,我是想如何来验证一下?
dachuannnnn 2013-06-24
  • 打赏
  • 举报
回复
引用 3 楼 bluewanderer 的回复:
system需要使用输出流的。另外我发现VC++貌似是根本不缓冲的,GCC是不换行就不显示。
你的意思是 linux下的时候 没有endl就不会显示?
加载更多回复(7)
语音识别的MATLAB实现 声控小车结题报告 小组成员:关世勇 吴庆林 一、 项目要求: 声控小车是科大华为科技制作竞赛命题组的项目,其要求是编写一个语言识别程序并适当改装一个小型机动车,使之在一个预先不知道具体形状的跑道上完全由声控来完成行驶比赛。跑道上可以有坡面,坑, 障碍等多种不利条件,小车既要具有较快的速度,也要同时具有较强的灵活性,能够克服上述条件。 二、 项目分析: 由于小车只要求完成跑道上的声控行驶,所以我们可以使用简单的单音命令来操作,如“前”、“后”、“左”、“右”等。 由于路面有各种不利条件,而且规则要求小车尽可能不越过边线,这就决定了我们的小车不能以较高的速度进行长时间的快速行驶。所以我们必须控制小车的速度和行进距离。 由于外界存在噪声干扰,所以我们必须对噪声进行处理以减小其影响。 鉴于上诉各种要求,我们决定对购买的遥控小车进行简单改造,使用PC机已有的硬件条件编写软件来完成语音的输入,采集,处理和识别,以实现对小车的控制。 三、 解决思路与模块: 整个程序大致可划分为三个模块,其结构框图如下图所示: 整个程序我们在Visual C++ 环境下编写。 四、 各模块的实现: 1 声音的采集: 将声音信号送入计算机,我们利用了声卡录音的低层操作技术,即对winmm.lib进行API调用。具体编程时这一部分被写在一个类(Soundin类)。 在构造函数设定包括最大采样率(11025),数据缓存(作为程序一次性读入的数据,2048),声卡本身所带的一些影响采样数据等的各种参数; 调用API函数waveInGetNumDevs(返回UNIT,参数为空)检察并打开声音输入设备,即声卡;并进而使用waveInGetDevCaps得到声卡的容量(在waveInCaps存有该数据,对其进行地址引用,从DWORD dwFormats得到最大采样率、声道数和采样位); 创建一个叫WaveInThreadEvent的事件对象,并赋予一个Handle,叫m_WaveInEvent,开始利用线程指针m_WaveInThread调用自定义的线程WaveInThreadProc; 对结构WAVEFORMATEXWaveInOpen开始提供录音设备。注意设备句柄的得到是通过对HWAVEIN 型数据m_WaveIn的引用。 由于通过这种方式进行录音的文件格式是.wav,所以要先设置录音长度,以及对头文件进行一些设置:包括buffer的地址为InputBuffer的初始地址,大小为录音长度的两倍,类型。使用waveInPrepareHeader为录音设备准备buffer。然后使用waveInAddBuffer函数为录音设备送出一个输入buffer。最后使用waveInStart(m_WaveIn)打开设备。 程序WaveInThreadProc需要提出另外说明,因为通过这个线程我们可以实现采样和数据提取。该线程首先定义一个指向CsoundIn类的指针pParam,并将其宏定义为PT_S。而线程参数即为空指针pParam。使用WaitForSingleObject将录音过程设置为一旦开始就不止(除非止线程)。在此线程做如下两个工作:将数据送入buffer,并将数据传入某个参数(其调用一个函数,将buffer的数据送入该函数的参数*pt),而这些数据正是我们要利用和处理的数字化的语音信息。 2 声音的预处理: 声音信息的预处理主要包括音头和音尾的判断,声音的预加重,分帧处理和窗化处理。 A 音头音尾的判断与提取: 这是该项目的一个难点。由于我们的声音信号不是连续给出的,而且现场还有噪声的存在,所以我们必须通过适当的方法来判断采集的数据是不是我们所要的声音控制信号。这又是该项目的一个重点。若声音指令信号提取的不恰当,那么我们采样所得的数据就和我们实际的语音信号就会有很大的出入,这样不但会延迟语音识别的时效性,而且会降低对这些声音信号的识别率。对声音信号的提取,主就是确定音头、音尾的位置。常用的方法有过零率和短时距能量等几种。我们这里采用的就是过零率这个方法。首先对噪声取样,从这些噪声样本得到噪声的上下限,将实时信号与这个门限进行比较,得到过零率。 定义过零率Zcr如下: 其: 利用过零率的大小来判断是否有声音信号进入,若 ( 为预设的过零率值),则表示有声音信号进入,就找到了音头。在找到音头的情况下,若 ,则表示声音结束,也就找到了音尾。在环境噪声较大且比声音指令小的多的情况下可以对这个门限加一修正。音头和音尾之间的部分就是我们用以作为识别用的声音指令信号了。由于一般情况下人们所发出的单音都有一定的时间长度而大的噪声则大多是突发的,持续时间较短,所以我们可以再对所得到的声音指令信号做一次筛选,若得到的声音信号的长度小于预设值,就可认为是噪声干扰,舍弃;若得到的声音信号的常到大于预设值,则将其作为有用信号存储。实验表明,利用过零率和预设长度相结合起来提取声音指令信号的方法很有效的。 B 语音信号的预加重: 我们所采用的预加重的方法是较为常用的网络: 传递函数为: 得到的信号为: 预加重的目的在于滤除低频干扰,尤其是50Hz或60Hz的工频干扰,将对于语音识别更为有用的高频部分的频谱进一步提升。在计算短时能量之前应用该滤波器,还可以起到消除直流漂移、抑制随机噪声和提升清音部分能量的效果。 C 分帧处理 在计算各个系数之前要先将语音信号作分帧处理。语音信号是瞬时变化的,但在10~20ms内是相对稳定的,而我们设定的采样频率为11025所以我们对预处理后的语音信号S1(n)以300点为一帧进行处理,帧移为100个采样点。 (N=300) D 窗化处理: 为了避免矩形窗化时对LPC系数在端点的误差,我们采用了汉明窗函数来进行窗化。即: 其: 3 语音数据的特征提取: 语音信号的特征有多种度量标准,我们采用的是比较常用的倒谱特征。 语音信号是一种典型的时变信号,然而如果把观察时间缩短到几十毫秒,则可以得到一系列近似稳定的信号。人的发音器官可以用若干段前后连接的声管进行模拟,这就是所谓的声管模型。全极点线性预测模型(LPC)可以对声管模型进行很好的描述,每段声管对应一个LPC模型的极点。一般情况下,极点的个数在12-16个之间就可以足够清晰地描述语音信号的特征了。 语音信号经过预处理,它的每个样值均可由过去若干个样值的线性组合来逼近,同时可以采用使实际语音抽样与线性预测抽样之间的均方差最小的方式,来解出一组预测的系数 。这就是LPC所提取出来的信号的初始特征。 预测值时域表达式为: 其, 为加权系数,即LPC系数。预测的误差为: 使 在均方误差最小的条件下,可求得唯一的 ,此过程即为LPC分析过程。 这里采用的是Levinson-Durbin法。由上面的式子有: 其, 为待分析与引信号的自相关序列: 因此:Levinson-Durbin算法为: 1. 初始化: 2. 迭代计算:对于 3. 最后就算: 以上式的 为反射系数。 ; 为最小预测误差,随着阶数的增加而减少; 为模型增益常量。 在语音识别系统,很少直接使用LPC系数,而是由LPC系数推导出另一种参数:线性预测倒谱系数(LPCC)。倒谱实际上是一种同态信号处理方法,标准的倒谱系数计算流程需要进行FFT变换、对数操作和相位校正等步骤,预算比较复杂。在实际计算,他不是由原始信号x(n)得到,而是由LPC系数 得到的。 LPC系数算出后,就可以直接进行倒谱系数 的计算,其迭代算法如下: 1.初始化: 2.迭代计算: 这里C(0)实际上就是直流分量,在识别通常是不用的,也不去计算。 综合考虑识别误差和识别速度的影响,我们在计算LPC 时,LPC系数的阶数Q值取为8,而LPCC系数的阶数P值取为12。 4 DTW 算法: 语音识别程序的核心部分即采用合适的算法来识别不同的语音信号,在特定人语音识别算法,对于孤立词语语音识别而言,最为简单的方法是采用DTW(Dynamic Time Warping,动态时间弯折)算法,该算法基于动态规划)(DP)的思想,解决了发音长短不一的模本匹配问题,是语音识别出现较早、较为经典的一种算法。我们这里采用的就是DTW算法。 我们用R表示已存的参考模板,T表示待识别的测试模板,R(1),R(2) ,…,R(m),T(1),T(2),…,T(n)分别表示参考模板和测试模板的各语音帧,d[T(n),R(m)]表示这两帧特征矢量之间的距离(DTW算法通常采用欧氏距离)。为了比较R和T之间的相似度,可以计算他们之间的距离D[T,R],距离越小则相似度越高。D[T,R]的计算通常采用的是动态规划的方法。 将R和T的各个帧号分别在直角坐标系的横轴和纵轴上标出,则如下图可得到一个网格,网格各点表示R和T的一帧的交汇点。DP算法可以归结为寻找一条通过此网格若干格点的路径,使得沿路径的累积距离达到最小值。 为了使路径不至于过分倾斜,可以约束斜率在0.5-2范围内,如果路径已经通过了格点( ),那么下一个通过的格点( )只能是下列三种情况之一: 搜索最佳路径的方法如下: 搜索从( )开始,网格任意一点只可能有一条路径通过。对于( ),其可达到该格点的前一格点之可能是 ( ),( ),( ),那么( )一定选择这3个距离的最小者所对应的格点作为其前续格点。若用( )代表此格点,并将通过该格点的路径延伸而通过( ),这时此路径的累积距离为: 其的 由下式决定: 这样可以从初始点出发依次搜索直到搜索到终点 便可得到最佳路径。 五、整个系统的软件流程图: 见右图。 六、硬件 用四个c1108型三极管来控制小车遥控手柄的前、后、左、右触点的通断。从计算机的并口引出四根信号线,与三极管相连,与前、后、左、右一一对应。若判断出指令信号后,则相应的信号线上输出高电平,该电路导通,发送无线信号。若无指令,则信号线上输出低电平,电路断路,不发送无线信号。电路示意图如下:(由于四条线路基本是一致的,这里只画出了其的一根信号线与外电路的连接示意图) 七、实现功能与技术指标: 1. 软件上可以识别前、后、左、右、停等语音指令,并发出相应的控制信号。 2. 硬件上可以实时的收发无限信号,并控制小 车作相应的动作。 3. 语音识别正确率大于95%,从发出语音指令 到执行该指令的延时小于100ms。 八、与原设计方案的比较: 我们的整个方案基本是按照原设计方案来进行的,各项指标也基本达到了预定目标。 九、经费使用情况: 主要分为两部分: 第一, 由于我们都没有学过语音识别方面的知识,所以一开始我们就买了一些参考书和资料。 第二, 在软件部分初步成型后,在对小车进行改装时购买了一些电子元器件以及其他一些工具。 十、致谢: 感谢华为研究所为我们提供这样好的锻炼机会,我们从学到了很多书本上学不到的知识。 感谢铁伟涛同学为我们提供方案支持。 感谢我的导师魏衡华老师和314实验室的所有负责人为我们提供PC机和其它硬件条件以及方便的实验环境。 感谢所有的评委老师在开题和期评审给我们提供很多宝贵的意见。

64,281

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧