Search code examples
c++sleep

Why does sleep not wait, no matter how high the value entered in the parentheses is?


I'm trying to rewrite a program that I have written earlier in C++ that connects to my laptop over ssh or sftp based on what the user types, that program works fine but I am trying to write the std::cout out letter by letter with a 200ms delay in between characters. Here's my current attempt(doesn't work):

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

int main()
{
std::cout << "S";
sleep(0.2);
std::cout << "S";
sleep(0.2);
std::cout << "H";
sleep(0.2);
std::cout << " o";
sleep(0.2);
std::cout << "r";
sleep(0.2);
std::cout << " S";
sleep(0.2);
std::cout << "F";
sleep(0.2);
std::cout << "T";
sleep(0.2);
std::cout << "P";
std::cout << "?\n" << ">"; 

std::string contype;
std::cin >> contype;
if(contype == "ssh")
{
system("ssh redacted");
}
if(contype == "sftp")
{
system("sftp redacted");
}
}

Solution

  • If you are using c++11, you should use thread and chrono to sleep for 200ms.

    #include <iostream>
    #include <stdlib.h>
    #include <string>
    #include <unistd.h>
    #include <chrono>
    #include <thread>
    
    int main()
    {
    std::cout << "S" << std::flush;
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
        std::cout << "S" << std::flush;
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
        std::cout << "H" << std::flush;
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
        std::cout << " o" << std::flush;
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
        std::cout << "r" << std::flush;
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
        std::cout << " S" << std::flush;
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
        std::cout << "F" << std::flush;
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
        std::cout << "T" << std::flush;
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
        std::cout << "P" << std::flush;
        std::cout << "?\n" << ">";
    
    std::string contype;
    std::cin >> contype;
    if(contype == "ssh")
    {
    system("ssh redacted");
    }
    if(contype == "sftp")
    {
    system("sftp redacted");
    }
    }
    

    should work just fine. Edit: you should output std::flush at the end of each output to explicitly flush the buffer.

    Edit 2: as mentioned in the comments, defining a constant instead of using the magic number upon every iteration is better. Another option is to define a function that goes over a string and prints each letter, then waits. This would like this -

    #include <iostream>
    #include <stdlib.h>
    #include <string>
    #include <unistd.h>
    #include <chrono>
    #include <thread>
    
    void printAndSleep(const std::string& msg, int timePeriod);
    
    int main()
    {
        const std::string msg = "SSH or SFTP";
        const int waitingTime = 200;
        printAndSleep(msg, waitingTime);
        std::cout << "?\n" << ">";
    
    std::string contype;
    std::cin >> contype;
    if(contype == "ssh")
    {
    system("ssh redacted");
    }
    if(contype == "sftp")
    {
    system("sftp redacted");
    }
    }
    
    void printAndSleep(const std::string& msg, int timePeriod){
        for (char c : msg) {
            std::cout << c << std::flush;
            std::this_thread::sleep_for(std::chrono::milliseconds(timePeriod));
        }
    }