清除cout缓冲区(c ++)

时间:2016-03-18 23:47:48

标签: c++ cout flush ostream

你好我正在写一个简短的程序来实现一个shell,我遇到了一个不寻常的问题。由于某种原因,我无法清除std :: cout缓冲区。该程序不会打印出消息。我理解一个简单的解决方案是切换到std :: cerr,但有没有办法用cout打印消息? 我尝试过的事情:

  1. std::cout.flush()
  2. 在将任何内容写入标准输出后插入std::endl
  3. std::flush插入输出流
  4. std::cout.setf(std::ios::unitbuf);我发现这应该是非缓冲输出。
  5. 我非常感谢任何帮助,我的代码是:

    int main()
    {
        //Tryed this to unbuffer cout, no luck.
        std::cout.setf(std::ios::unitbuf);
    
        std::string input;
    
        //Print out shell prompt and read in input from keyboard.
        std::cout << "myshell> ";   
        std::getline(std::cin, input);
    
        //**********************************************************************
        //Step 1) Read in string and parse into tokens.
        //**********************************************************************
    
        char * buf = new char[input.length() + 1];
        strcpy(buf, input.c_str());
    
        int index = 0;
        char * command[256]; 
    
        command[index] = std::strtok(buf, " ");    //Get first token.
        std::cout << command[index] << std::endl;
    
        while (command[index] != NULL)
        {
            ++index;
            command[index] = std::strtok(NULL," ");    //Get remaining tokens.
            std::cout << command[index] << std::endl;
        }   
    
        std::cout.flush(); //No luck here either
    
        //HERE IS WHERE MY PROBLEM IS.
        std::cout << index << " items were added to the command array" << std::endl;
    
        delete[] buf;
    
        return 0;   
    }
    

2 个答案:

答案 0 :(得分:4)

问题是,您在NULL循环的最后一次迭代中向cout发送了while,这导致了UB,并且在您的情况下正在干扰{{1} }。在向cout发送任何内容之前检查NULL,您没问题:

cout

答案 1 :(得分:1)

如果您需要知道您的信息流发生了什么,请记住他们可以携带状态信息(the iostate, which I recommend you read about)。以下代码可能有助于跟踪您的错误:

 try {
      std::cout.exceptions(std::cout.failbit);          
 } catch(const std::ios_base::failure& e) {
      std::cerr << "stream error: " << e.what() << std::endl;
      std::cout.clear();
 }

 // continue working with cout, because std::cout.clear() removed
 // failbit

或者,甚至更简单:

if(not std::cout) {
    // address your error (if it is recoverable)
 }

这就是您的代码的样子:

#include <cstring>
#include <string>
#include <iostream>
int main()
{
    //Tryed this to unbuffer cout, no luck.
    std::cout.setf(std::ios::unitbuf);

    std::string input;

    //Print out shell prompt and read in input from keyboard.
    std::cout << "myshell> ";   
    std::getline(std::cin, input);

    //**********************************************************************
    //Step 1) Read in string and parse into tokens.
    //**********************************************************************

    char * buf = new char[input.length() + 1];
    strcpy(buf, input.c_str());

    int index = 0;
    char * command[256]; 

    command[index] = std::strtok(buf, " ");    //Get first token.
    std::cout << command[index] << std::endl;

    while (command[index] != NULL)
    {
        ++index;
        command[index] = std::strtok(NULL," ");    //Get remaining tokens.
        std::cout << command[index] << std::endl;
    }

    // I added from here...
    if(not std::cout) {
      std::cerr << "cout is messed up... fixing it..." << std::endl;
      std::cout.clear();
    }
    // ... to here.

    std::cout.flush(); //No luck here either

    //HERE IS WHERE MY PROBLEM IS.
    std::cout << index << " items were added to the command array" << std::endl;

    delete[] buf;

    return 0;   
}

结果:

$ ./a.out
myshell> 1 2 3
1
2
3
cout is messed up... fixing it...
3 items were added to the command array