Cin Show Default Value - c++

With C++ is it possible to give the user a default value with the Cin statement, then have them backspace what they want to change? For instance: I give the user an option to change a string name, I output the name to the screen: "John Doe" and they can backspace to change the name to "John Smith".

For features like this and a lot more, take a look at GNU Readline or one of its workalikes. It's basically a library for applications to support command-line editing with familiar features like up-arrow to repeat previous commands, editing of those previous commands, and yes, you can customize the text presented to the user who can then edit it with the same keystrokes one would use in the shell.

I might be crazy, but here's a plain Windows solution that works on Visual Studio 2012 Update 1. It simulates the characters you want entered, which should keep them in the input buffer until they're ready to be read, and then reads input, waiting for a newline.
#include <iostream>
#include <string>
#include <windows.h>
void InsertDefaultName(const std::string &def) {
HWND hwnd = GetConsoleWindow();
for (char c : def) {
SendMessage(hwnd, WM_CHAR, c, 0);
}
}
int main() {
std::cout << "Enter name: ";
std::string name;
InsertDefaultName("John Doe");
std::getline(std::cin, name);
std::cout << "You entered " << name << '\n';
}
It's worth noting that this might not work completely properly if the user is, say, holding down a key before it gets to the InsertDefaultName() function call. A more robust library is definitely better, but this is here if it works well enough for you without a whole new library.

Related

Let user type in the middle of string (c/c++)?

Normally c/cpp string displayed in console only allows user to type after it.
Is there any simple way to let user to type in the middle of the output string, e.g fill in the blank:
Mr ____ is the teacher.
std::cout can print it easily, but how to let user type directly in the blank with simple code and read it? And e.g. if the name is long the move the printed character to the right?
You're looking for controlling a console/terminal. Neither of the languages you ask about has any notion of that -- they both only know streams of input and output. This is a simple abstraction, input and output are done character by character, in sequence. Input doesn't have to come from a keyboard, output doesn't have to be a screen or terminal ...
Controlling the contents of a screen is very platform-dependent. If you are on windows, the windows API provides a bunch of functions for controlling a console.
If you want to do something cross-platform, have a look at curses. There are implementations for many platforms, like ncurses (often used on *nix systems) and pdcurses (which is quite good for windows) and they all provide the same interface.
To learn about curses programming, the NCURSES Programming HOWTO is a good start. Just replace #include <ncurses.h> with #include <curses.h> so your code isn't tied specifically to ncurses but works with any curses implementation.
Yes, you can absolutely do this (I mean, ever played snake? All games were on terminals back then, and your problem is much simpler than writing a game).
A trick is using \r, which is a carriage return. That character will slide you back to the start of the line, allowing you to overwrite the previous string. This is commonly used for loading animations like
[---]
[=---]
[==-]
[===]
To prevent forcing the user to hit enter before sending data, I'll show a Linux/Mac solution.
system("/bin/stty raw"); // Get keystrokes immediately, #include <stdlib.h>
string s;
char c;
cout << "Mr _ is the teacher." << flush;
while( c = getchar() ) { // #include <stdio.h>
if( c == 3 ) // CTRL+C
exit(1);
if( c == 13 ) { // Newline
cout << endl;
break;
}
if( c == 127 ) { // Backspace
if( s.size() > 0 )
s.pop_back();
} else {
s += c;
}
cout << "\r"; // Reset the cursor
cout << "Mr " << s << "_ is the teacher. " << flush; // Spaces to cover invalid backspace character
cout << "\r"; // Reset the cursor
cout << "Mr " << s << "_ is the teacher." << flush;
}
system("/bin/stty cooked"); // Go back to buffered input
This can be done in Windows by importing #include<conio.h>, and then using getch() instead of getchar(). (You don't need any stty system commands)
Make sure to use your platform-specific #ifdef's to make your code portable!

read txt file in c++ (chinese)

I'm trying to develop function that check whether chinese word which user enters is in the txt file or not. The following is the code. But it is not working. I want to know what the problem is. Help me please.
setlocale(LC_ALL, "Chinese-simplified");
locale::global(locale("Chinese_China"));
SetConsoleOutputCP(936);
SetConsoleCP(936);
bool exist = FALSE;
cout << "\n\n <Find the keyword whether it is in that image or not> \n ";
cout << "Enter word to search for: ";
wstring search;
wcin >> search; //There is a problem to enter chinese.
wfstream file_text("./a.txt");
wstring line;
wstring::size_type pos;
while (getline(file_text, line))
{
pos = line.find(search);
if (pos != wstring::npos) // string::npos is returned if string is not found
{
cout << "Found!" << endl;
exist = true;
break;
}
}
when I use this code, The result is as follows.
const int oldMbcp = _getmbcp();
_setmbcp(936);
const std::locale locale("Chinese_China.936");
_setmbcp(oldMbcp);
If you're interested in more details, please see stod-does-not-work-correctly-with-boostlocale for a more detailed description of how locale works,
In a nutshell the more interesting part for you:
std::stream (stringstream, fstream, cin, cout) has an inner locale-object, which matches the value of the global C++ locale at the moment of the creation of the stream object. As std::in is created long before your code in main is called, it has most probably the classical C locale, no matter what you do afterwards.
you can make sure, that a std::stream object has the desirable locale by invoking std::stream::imbue(std::locale(your_favorit_locale)).
I would like to add the following:
It is almost never a good idea to set the global locale - it might break other parts of the program or third part libraries - you never know.
std::setlocale and locale::global do slightly different things, but locale::global resets not only the global c++-locale but also the c-locale (which is also set by std::setlocale, not to be confused with the classical "C" locale), so you should call it in another order if you want to have c++ locale set to Chinese_China and C locale to chinese-simplified
First
locale::global(locale("Chinese_China"));
And than
setlocale(LC_ALL, "Chinese-simplified");
Try locale::global(locale("Chinese_China.936")); or locale::global(locale(""));
And for LC_ALL "chinese-simplified" or "chs"
If using Vladislav's answer does not solve this, take a look at answer to stl - Shift-JIS decoding fails using wifstrem in Visual C++ 2013 - Stack Overflow:
const int oldMbcp = _getmbcp();
_setmbcp(936);
const std::locale locale("Chinese_China.936");
_setmbcp(oldMbcp);
There appears to be a bug in Visual Studio's implementation of locales. See also c++ - double byte character sequence conversion issue in Visual Studio 2015 - Stack Overflow.

Invalid input for std::cin

The following code is intended to concatenate words entered by the user.
#include <iostream>
#include <string>
int main() {
// insert code here...
std::string s;
std::string concString;
while (std::cin >> s)
{
concString = concString + s;
}
std::cout << concString << std::endl;
return 0;
}
I am stuck in this while loop during execution because of which I am not able to print the concatenated string. How do I exit this loop? What is an invalid input for std::cin?
Typically, a loop like that is stopped by end of file, rather than invalid input.
In a *nix environment, you can usually send an end of file to the terminal with CTRL+d, and at a windows console, CTRL+z.
See https://stackoverflow.com/a/16136924/1084944
You could, however, implement your own additional way to signify end of input. For example, having your users enter a blank line when done, or the word quit or such. Once you've chosen one, you should communicate that to the user, and you will have to structure your loop to be able to detect these conditions and exit.

Reading a combination without confirming with enter?

So basically I just want to read characters from the user and make my code know that when user types a defined combination (say, CTRL+F - but without confirming with Enter, for exmaple), it's the end of the input. How can I do that? I only know how to read characters with enter and comparing their ASCII's...
EDIT
Reading through your question again, I realize that I misinterpreted your question. I'll leave this since it might still be useful to you or others.
What you're asking for doesn't have to do much with reading characters. In fact, CTRL is not a character at all. You're basically just checking for key pushes. Handling this kind of input is platform dependent, and even on a single platform, multiple methods will exist. One way to do it for windows is by using GetAsyncKeyState. This function will check whether a specified key is being pushed right now. Note that it doesn't 'remember' input, so you'll have to check this function many times per second to register all user input.
You supply the function with a single argument specifying the key of which you want to check the state. A list of all key codes can be found here
Example:
#include <iostream> //for output
#include <windows.h> //for GetAsyncKeyState
int main()
{
while(true)
{
if( GetAsyncKeyState(VK_CONTROL) ) //CTRL-key is pressed
{
if( GetAsyncKeyState( 0x46 ) ) //F-key is pressed
std::cout << "CTRL-F is pressed" << std::endl;
if( GetAsyncKeyState( 0x58 ) ) //X-key is pressed
break;
}
}
std::cout << "CTRL-X was pressed, stopping.." << std::endl;
}
This example will continuously check if CTRL-F is being pushed and if so write output, until CTRL-X is pressed.
The Windows system call ReadConsoleInput allows you to read console input directly. You may want to wrap that call into a function that just extracts the essential data from the several parameters of the ReadConsoleInput function. You can write a function to check if there is any input using GetNumberOfConsoleInputEvents.
try
#include <conio.h>
#include <iostream>
using namespace std;
int main()
{
bool keepGoing = true;
char key = ' ';
while (keepGoing){
cout << "Enter a key" << endl;
while(_kbhit()){
key = _getch();
cout << "You entered: " << key << endl;
}
}
}
then specify delimiter when to end loop.
if on linux curses are available. there is also a getch function. you should use curses if you aim for cross platform compatibility. ncurses library functions are similar to ones in conio.h.
ncurses tutorial

Is there a decent wait function in C++?

One of the first things I learned in C++ was that
#include <iostream>
int main()
{
std::cout<<"Hello, World!\n";
return 0;
}
would simply appear and disappear extremely quickly without pause. To prevent this, I had to go to notepad, and save
helloworld.exe
pause
ase
helloworld.bat
This got tedious when I needed to create a bunch of small test programs, and eventually I simply put while(true); at the end on most of my test programs, just so I could see the results. Is there a better wait function I can use?
you can require the user to hit enter before closing the program... something like this works.
#include <iostream>
int main()
{
std::cout << "Hello, World\n";
std::cin.ignore();
return 0;
}
The cin reads in user input, and the .ignore() function of cin tells the program to just ignore the input. The program will continue once the user hits enter.
Link
Please note that the code above was tested on Code::Blocks 12.11 and Visual Studio 2012
on Windows 7.
For forcing your programme stop or wait, you have several options :
sleep(unsigned int)
The value has to be a positive integer in millisecond.
That means that if you want your programme wait for 2 seconds, enter 2000.
Here's an example :
#include <iostream> //for using cout
#include <stdlib.h> //for using the function sleep
using namespace std; //for using cout
int main(void)
{
cout << "test" << endl;
sleep(5000); //make the programme waiting for 5 seconds
cout << "test" << endl;
sleep(2000); // wait for 2 seconds before closing
return 0;
}
If you wait too long, that probably means the parameter is in seconds. So change it to this:
sleep(5);
For those who get error message or problem using sleep try to replace it by _sleep or Sleep especially on Code::Bloks.
And if you still getting problems, try to add of one this library on the beginning of the code.
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <dos.h>
#include <windows.h>
system("PAUSE")
A simple "Hello world" programme on windows console application would probably close before you can see anything. That the case where you can use system("Pause").
#include <iostream>
using namespace std;
int main(void)
{
cout << "Hello world!" << endl;
system("PAUSE");
return 0;
}
If you get the message "error: 'system' was not declared in this scope" just add
the following line at the biggining of the code :
#include <cstdlib>
cin.ignore()
The same result can be reached by using cin.ignore() :
#include <iostream>
using namespace std;
int main(void)
{
cout << "Hello world!" << endl;
cin.ignore();
return 0;
}
cin.get()
example :
#include <iostream>
using namespace std;
int main(void)
{
cout << "Hello world!" << endl;
cin.get();
return 0;
}
getch()
Just don't forget to add the library conio.h :
#include <iostream>
#include <conio.h> //for using the function getch()
using namespace std;
int main(void)
{
cout << "Hello world!" << endl;
getch();
return 0;
}
You can have message telling you to use _getch() insted of getch
Lots of people have suggested POSIX sleep, Windows Sleep, Windows system("pause"), C++ cin.get()… there's even a DOS getch() in there, from roughly the late 1920s.
Please don't do any of these.
None of these solutions would pass code review in my team. That means, if you submitted this code for inclusion in our products, your commit would be blocked and you would be told to go and find another solution. (One might argue that things aren't so serious when you're just a hobbyist playing around, but I propose that developing good habits in your pet projects is what will make you a valued professional in a business organisation, and keep you hired.)
Keeping the console window open so you can read the output of your program is not the responsibility of your program! When you add a wait/sleep/block to the end of your program, you are violating the single responsibility principle, creating a massive abstraction leak, and obliterating the re-usability/chainability of your program. It no longer takes input and gives output — it blocks for transient usage reasons. This is very non-good.
Instead, you should configure your environment to keep the prompt open after your program has finished its work. Your Batch script wrapper is a good approach! I can see how it would be annoying to have to keep manually updating, and you can't invoke it from your IDE. You could make the script take the path to the program to execute as a parameter, and configure your IDE to invoke it instead of your program directly.
An interim, quick-start approach would be to change your IDE's run command from cmd.exe <myprogram> or <myprogram>, to cmd.exe /K <myprogram>. The /K switch to cmd.exe makes the prompt stay open after the program at the given path has terminated. This is going to be slightly more annoying than your Batch script solution, because now you have to type exit or click on the red 'X' when you're done reading your program's output, rather than just smacking the space bar.
I assume usage of an IDE, because otherwise you're already invoking from a command prompt, and this would not be a problem in the first place. Furthermore, I assume the use of Windows (based on detail given in the question), but this answer applies to any platform… which is, incidentally, half the point.
The appearance and disappearance of a window for displaying text is a feature of how you are running the program, not of C++.
Run in a persistent command line environment, or include windowing support in your program, or use sleep or wait on input as shown in other answers.
the equivalent to the batch program would be
#include<iostream>
int main()
{
std::cout<<"Hello, World!\n";
std::cin.get();
return 0;
}
The additional line does exactly what PAUSE does, waits for a single character input
There is a C++11 way of doing it. It is quite simple, and I believe it is portable. Of course, as Lightness Races in Orbit pointed out, you should not do this in order to be able to see an Hello World in your terminal, but there exist some good reason to use a wait function. Without further ado,
#include <chrono> // std::chrono::microseconds
#include <thread> // std::this_thread::sleep_for
std::this_thread::sleep_for(std::chrono::microseconds{});
More details are available here. See also sleep_until.
Actually, contrary to the other answers, I believe that OP's solution is the one that is most elegant.
Here's what you gain by using an external .bat wrapper:
The application obviously waits for user input, so it already does what you want.
You don't clutter the code with awkward calls. Who should wait? main()?
You don't need to deal with cross platform issues - see how many people suggested system("pause") here.
Without this, to test your executable in automatic way in black box testing model, you need to simulate the enter keypress (unless you do things mentioned in the footnote).
Perhaps most importantly - should any user want to run your application through terminal (cmd.exe on Windows platform), they don't want to wait, since they'll see the output anyway. With the .bat wrapper technique, they can decide whether to run the .bat (or .sh) wrapper, or run the executable directly.
Focusing on the last two points - with any other technique, I'd expect the program to offer at least --no-wait switch so that I, as the user, can use the application with all sort of operations such as piping the output, chaining it with other programs etc. These are part of normal CLI workflow, and adding waiting at the end when you're already inside a terminal just gets in the way and destroys user experience.
For these reasons, IMO .bat solution is the nicest here.
What you have can be written easier.
Instead of:
#include<iostream>
int main()
{
std::cout<<"Hello, World!\n";
return 0;
}
write
#include<iostream>
int main()
{
std::cout<<"Hello, World!\n";
system("PAUSE");
return 0;
}
The system function executes anything you give it as if it was written in the command prompt. It suspends execution of your program while the command is executing so you can do anything with it, you can even compile programs from your cpp program.
Syntax:
void sleep(unsigned seconds);
sleep() suspends execution for an interval (seconds).
With a call to sleep, the current program is suspended from execution for the number of seconds specified by the argument seconds. The interval is accurate only to the nearest hundredth of a second or to the accuracy of the operating system clock, whichever is less accurate.
This example should make it clear:
#include <dos.h>
#include <stdio.h>
#include <conio.h>
int main()
{
printf("Message 1\n");
sleep(2); //Parameter in sleep is in seconds
printf("Message 2 a two seconds after Message 1");
return 0;
}
Remember you have to #include dos.h
EDIT:
You could also use winAPI.
VOID WINAPI Sleep(
DWORD dwMilliseconds
);
Sleep Function(Windows)
Just a note,the parameter in the function provided by winapi is in milliseconds ,so the sleep line at the code snippet above would look like this "Sleep(2000);"
getchar() provides a simplistic answer (waits for keyboard input).
Call Sleep(milliseconds) to sleep before exit.
Sleep function (MSDN)
You can use sleep() or usleep().
// Wait 5 seconds
sleep( 5 );
Well, this is an old post but I will just contribute to the question -- someone may find it useful later:
adding 'cin.get();' function just before the return of the main() seems to always stop the program from exiting before printing the results: see sample code below:
int main(){
string fname, lname;
//ask user to enter name first and last name
cout << "Please enter your first name: ";
cin >> fname;
cout << "Please enter your last name: ";
cin >> lname;
cout << "\n\n\n\nyour first name is: " << fname << "\nyour last name is: "
<< lname <<endl;
//stop program from exiting before printing results on the screen
cin.get();
return 0;
}
Before the return statement in you main, insert this code:
system("pause");
This will hold the console until you hit a key.
#include<iostream>
#include<string>
using namespace std;
int main()
{
string s;
cout << "Please enter your first name followed by a newline\n";
cin >> s;
cout << "Hello, " << s << '\n';
system("pause");
return 0; // this return statement isn't necessary
}
The second thing to learn (one would argue that this should be the first) is the command line interface of your OS and compiler/linker flags and switches.