I am writing a console based program to show a friend what I can do with C++. My project acts as if the user is speaking to a thinking "computer" and has various moments that pause (using cout.flush(); _sleep();) to mimic the "computer" thinking before it answers. What I would like to do is have each letter of the "computers" response come in a delay, on letter after another, so that it appears as if the "computer" is actually typing it's response. Below is my code thus far. It is unfinished (obviously) because I got the idea for the "typed response" while working. I am also unsure of how to mask the user input for the password (to display an asterisk instead of the inputted letter). I halted progress until I can figure this out...
First off, thank you for taking the time to reply. I still have a problem though. When I try and use your code, I get the following header file c++0x_warning.h . I suppose it's also a good time to mention that I haven't coded in a little over 5 years so, and I should follow my own words here, not having comments in your code is making it a little hard to follow. (EXAMPLE: Should I not use usingnamespace std; ?). Anyway, here is the contents of the header file I receive.
// Copyright (C) 2007-2014 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/c++0x_warning.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iosfwd}
*/
#ifndef _CXX0X_WARNING_H
#define _CXX0X_WARNING_H 1
#if __cplusplus < 201103L
#error This file requires compiler and library support for the \
ISO C++ 2011 standard. This support is currently experimental, and must be \
enabled with the -std=c++11 or -std=gnu++11 compiler options.
#endif
#endif
A Sidenote... I need to figure out masking as well, if you have any experience.
> This file requires compiler and library support for the ISO C++ 2011 standard.
> This support is currently experimental, and must be
> enabled with the -std=c++11 or -std=gnu++11 compiler options.
Compile with -std=c++11
For example, g++ -std=c++11 -O3 -Wall -Wextra -pedantic-errors
If possible, update the compiler/library to a more current version (GCC 5.3 or above)
#include <iostream>
#include <string>
#include <chrono>
#include <thread>
struct with_delay // helper type to print strings with delay between characters
{
const std::string text ;
with_delay( std::string str ) : text(str) {}
with_delay( constchar* cstr ) : text(cstr) {}
// overloaded operator to print the string with delay
friend std::ostream& operator<< ( std::ostream& stm, const with_delay& delayed )
{
// closure (lambda) see: http://www.stroustrup.com/C++11FAQ.html#lambda
// uses the thread support library: http://en.cppreference.com/w/cpp/thread/sleep_for
// time duartion in milliseconds: http://en.cppreference.com/w/cpp/chrono/duration
// type deduction with auto: http://www.stroustrup.com/C++11FAQ.html#autostaticconstauto sleep = [] ( unsignedint msecs )
{ std::this_thread::sleep_for( std::chrono::milliseconds(msecs) ) ; };
// range based for see: http://www.stroustrup.com/C++11FAQ.html#forfor( char c : delayed.text ) // for each character in text
{
if( std::isspace(c) ) sleep(600) ; // white space: pause for 600 millisecs
if( c == '.' ) sleep(400) ; // period: pause for 400 millisecs
stm << c << std::flush ;
sleep(200) ; // pause for 200 millisecs after each character
}
return stm ;
}
};
// helper function to print cnt number of periods ... with delay
with_delay wait( unsignedint cnt ) { return with_delay( std::string( cnt, '.' ) ) ; }
// user defined literal for convenience. eg. std::cout << "xxy"_slowly ; will print "xyz" with delay between characters
// see: http://www.stroustrup.com/C++11FAQ.html#UD-literals
with_delay operator"" _slowly( constchar* literal, std::size_t ) { return literal ; }
int main()
{
std::cout << "this is the program 'space2001.exe'\n\n"
<< "the program is initialising. " << "please wait "_slowly
<< wait(10) << "\n\n"
<< "I am your 'heuristically programmed algorithmic computer' ""existing as one of our\nseries 9000 units."_slowly << '\n';
}
This is a lot less realistic than @JLBorges' code, which has different delays for different types of character. However, the code below is simple (simplistic?) and I've put a few comments in it.
Both threads and timer require C++11. If you are using MinGW's g++ compiler or something similar then you ought to be able to compile with g++ -std=c++11 , but I've never managed to get this to work with threads (and, looking on the internet, I'm not alone). In the end I had to run the compiler that comes with Visual Studio, cl.exe (from the normal Windows command line, not the VS IDE). You can also compile and run the code through cpp-shell from this forum; (gear wheel outside the top right-hand corner of code samples).
If you have some other library that will put in an appropriate delay (and it looks like you have), then just change line 13 and you can do away with threads and chrono.
#include <iostream>
#include <string>
#include <thread> // for this_thread::sleep_for (needs C++11)
#include <chrono> // for chrono::milliseconds (needs C++11)
usingnamespace std;
//======================================================================
void delay( unsignedint msecs ) // puts in a delay of msecs milliseconds
{
this_thread::sleep_for( chrono::milliseconds( msecs ) );
}
//======================================================================
void typedText( string text, unsignedint msecs ) // enters text with a delay of msecs milliseconds between characters
{
for ( int i = 0; i < text.size(); i++ ) // for each character in text
{
delay( msecs ); // put in a delay
cout << text[i] << flush; // output the character (and flush the buffer)
}
}
//======================================================================
int main()
{
string text;
text = "Ubuntu Linux\n" ; typedText( text, 5 );
text = "ZX Spectrum\n" ; typedText( text, 50 );
text = "Microsoft Windows\n"; typedText( text, 500 );
text = "My cat running across the keyboard\n" ; typedText( text, 1 );
}