Letters stored as integers - while-loop

#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "Please enter an integer between 1 and 5" << endl;
int x; //Selection of menu prompt
cin >> x;
while (x < 1 || x > 5) //Tossing out garbage input
{
cout << "Invalid selection, please make another." << endl;
cin >> x;
}
return 0;
}
When this is run, entering "a" for example, enters the while loop, but does not wait for user input at "cin >> x;" and instead loops infinitely through. Can someone explain to me why this happens and how I might fix the issue? I can only imagine it is something to do with the keyboard buffer.

In this code, it's possible for cin to enter an error state. If the user does not enter an integer, it will fail.
That is, if the user enters a, then cin >> x does not set x, and future calls to cin >> x do not block. You see an endless loop.
You can check for this failure status and clear it. before continuing using code similar to:
if (cin.fail())
{
cin.clear();
cin.ignore();
cerr << "Invalid selection, please make another." << endl;
}

You really should use cin.clear() and cin.ignore() after accepting the input.
cin.clear() clears the error flag on cin, and then cin.ignore(5000, '\n') skips to the next newline. It will skip up to 5000 characters, so the code is assuming the user will not put in a very long.

Related

CGAL example cannot read input files?

this is my first stackoverflow question, so I hope the following text meets the question requirements. If not, please tell me what needs to be changed so I can adapt the question.
I'm new to CGAL and C++ in general. I would like to use CGAL 5.0.2 on a Macbook Pro early 2015 with macOS Catalina Version 10.15.4.
So to begin with, I followed the instruction steps given by the CGAL documentation using the package manager Homebrew. Since CGAL is a header-only library I configured it using CMake, as is recommended by the documentation.
It all worked out fine, so I went on trying the recommended examples given in the file CGAL-5.0.2.tar.xz, which is provided here. I'm particularly interested in the example Voronoi_Diagram_2.
Using the Terminal I executed the command -DCGAL_DIR=$HOME/CGAL-5.0.2 -DCMAKE_BUILD_TYPE=Release . in the example folder called Voronoi_Diagram_2. Then I executed the command make. All went well, no error messages were prompted. But executing the resulting exec file didn't produce any results.
After some research I managed to modify the code in a way that it prints the values of some variables. Problem seems to be that the input file which contains the line segments for which the voronoi diagramm shall be calculated is not correctly read.
The while loop which I highlighted in the code below by inserting //// signs seems not to be entered. That's why I assume that the variable ifs is empty, even though the input file "data1.svd.cin", which can be found in the folder "data" of the example, wasn't.
Does anyone have an idea for the reasons of this behaviour? Any help is appreciated.
This is the vd_2_point_location_sdg_linf.cpp file included in the example, which I modified:
// standard includes
#include <iostream>
#include <fstream>
#include <cassert>
// includes for defining the Voronoi diagram adaptor
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Segment_Delaunay_graph_Linf_filtered_traits_2.h>
#include <CGAL/Segment_Delaunay_graph_Linf_2.h>
#include <CGAL/Voronoi_diagram_2.h>
#include <CGAL/Segment_Delaunay_graph_adaptation_traits_2.h>
#include <CGAL/Segment_Delaunay_graph_adaptation_policies_2.h>
// typedefs for defining the adaptor
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Segment_Delaunay_graph_Linf_filtered_traits_2<K> Gt;
typedef CGAL::Segment_Delaunay_graph_Linf_2<Gt> DT;
typedef CGAL::Segment_Delaunay_graph_adaptation_traits_2<DT> AT;
typedef CGAL::Segment_Delaunay_graph_degeneracy_removal_policy_2<DT> AP;
typedef CGAL::Voronoi_diagram_2<DT,AT,AP> VD;
// typedef for the result type of the point location
typedef AT::Site_2 Site_2;
typedef AT::Point_2 Point_2;
typedef VD::Locate_result Locate_result;
typedef VD::Vertex_handle Vertex_handle;
typedef VD::Face_handle Face_handle;
typedef VD::Halfedge_handle Halfedge_handle;
typedef VD::Ccb_halfedge_circulator Ccb_halfedge_circulator;
void print_endpoint(Halfedge_handle e, bool is_src) {
std::cout << "\t";
if ( is_src ) {
if ( e->has_source() ) std::cout << e->source()->point() << std::endl;
else std::cout << "point at infinity" << std::endl;
} else {
if ( e->has_target() ) std::cout << e->target()->point() << std::endl;
else std::cout << "point at infinity" << std::endl;
}
}
int main()
{
std::ifstream ifs("data/data1.svd.cin");
assert( ifs );
VD vd;
Site_2 t;
// /////////// Inserted Comment ////////////////////////////////
std::cout << "In the following the insertion from ifs should take place" << std::flush;
// ///////////////// while loop which doesn't seem to be active //////////////////
while ( ifs >> t ) {
// Existing Code to insert the points in the voronoi structure
vd.insert(t);
// Inserted Code to check if while loop is entered
std::cout << "Entered while loop" << std::flush;
}
// ///////////////////////////////////////////////////////////////////////////////
ifs.close();
assert( vd.is_valid() );
std::ifstream ifq("data/queries1.svd.cin");
assert( ifq );
Point_2 p;
while ( ifq >> p ) {
std::cout << "Query point (" << p.x() << "," << p.y()
<< ") lies on a Voronoi " << std::flush;
Locate_result lr = vd.locate(p);
if ( Vertex_handle* v = boost::get<Vertex_handle>(&lr) ) {
std::cout << "vertex." << std::endl;
std::cout << "The Voronoi vertex is:" << std::endl;
std::cout << "\t" << (*v)->point() << std::endl;
} else if ( Halfedge_handle* e = boost::get<Halfedge_handle>(&lr) ) {
std::cout << "edge." << std::endl;
std::cout << "The source and target vertices "
<< "of the Voronoi edge are:" << std::endl;
print_endpoint(*e, true);
print_endpoint(*e, false);
} else if ( Face_handle* f = boost::get<Face_handle>(&lr) ) {
std::cout << "face." << std::endl;
std::cout << "The vertices of the Voronoi face are"
<< " (in counterclockwise order):" << std::endl;
Ccb_halfedge_circulator ec_start = (*f)->ccb();
Ccb_halfedge_circulator ec = ec_start;
do {
print_endpoint(ec, false);
} while ( ++ec != ec_start );
}
std::cout << std::endl;
}
ifq.close();
return 0;
}

Trouble with limiting user's input

For the following, Im trying to limit the users input to only Y or y or N or n. Please follow my comments on the codes so I can point out what the problem is. I'm very new to this forum, I have a lot of passion for programming, please help me if anyone can. THANK YOU. The while loop(not the do-while loop) is the part I'm having trouble with. I think maybe I didn't use the != correctly. I haven't anything too advance yet, the class I'm in right now is just introductory level.
cout << "Would you like to use this program again?: ",
cin >> ans;
if(ans =='Y'||ans =='y'||ans =='N'||ans =='n')
break;
else //This is where I'm having problem with.
while (ans != 'Y'||ans != 'y'||ans !='N'||ans !='n')
{
cout << "Please enter Y or y if you like to use the program again and N or n do exit.",
cin >> ans; //If the question is asked and no matter what I input for ans, the while loop never gets exited. Why? Is there something I didn't use right?
}
}while (ans == 'Y'||ans =='y');
return 0;
A better way to handle your logic would be to have a single do loop which continually prompts the user for yes/no input until he gives it:
do {
cout << "Please enter Y or y if you like to use the program again and N or n do exit.",
cin >> ans;
} while (ans != 'Y' || ans != 'y' || ans !='N' || ans !='n');

wcout function does not print a french character

I am using the wcin in order to store a single character in a wchar_t. Then I try to print it with a wcout call and the french character 'é' : but I can't see it at my console.
My compiler is g++ 4.5.4 and my OS is Ubuntu 12.10 64 bits.
Here is my attempt (wideChars.cpp) :
#include <iostream>
int main(){
using namespace std;
wchar_t aChar;
cout << "Enter your char : ";
wcin >> aChar;
wcout << L"You entered " << aChar << L" .\n";
return 0;
}
When I lauch the programm :
$ ./wideChars
Enter your char : é
You entered .
So, what's wrong with this code ?
First, add some error checking. Test what does wcin.good() return after the input and what does wcout.good() return after the "You entered" print? I suspect one of those will return false.
What are your LANG and LC_* environment variables set to?
Then try to fix this by adding this at the top of your main(): wcin.imbue(std::locale("")); wcout.imbue(std::locale(""));
I do not have my Ubuntu at hand right now, so I am flying blind here and mostly guessing.
UPDATE
If the above suggestion does not help then try to construct locale like this and imbue() this locale instead.
std::locale loc (
std::locale (),
new std::codecvt_byname<wchar_t, char, std::mbstate_t>("")));
UPDATE 2
Here is what works for me. The key is to set the C locale as well. IMHO, this is a bug in GNU C++ standard library implementation. Unless I am mistaken, setting std::locale::global(""); should also set the C library locale.
#include <iostream>
#include <locale>
#include <clocale>
#define DUMP(x) do { std::wcerr << #x ": " << x << "\n"; } while (0)
int main(){
using namespace std;
std::locale loc ("");
std::locale::global (loc);
DUMP(std::setlocale(LC_ALL, NULL));
DUMP(std::setlocale(LC_ALL, ""));
wcin.imbue (loc);
DUMP (wcin.good());
wchar_t aChar = 0;
wcin >> aChar;
DUMP (wcin.good());
DUMP ((int)aChar);
wcout << L"You entered " << aChar << L" .\n";
return 0;
}
UPDATE 3
I am confused, now I cannot reproduce it again and setting std::locale::global(loc); seems to do the right thing wrt/ the C locale as well.

how interrupt c++ run without typing neither CTRL-C nor introducing cin or system-pause?

I need to do very long simulation, let's say this:
int i;
vector result;
while(true)
{
i = random(8);
if (i < 4) {result.push_back(i);}
}
cout << result;
Is there a way to stop this while loop from console doing something (e.g. pressing a key) without typing CTRL-C or without introducing a cin or system-pause function?
I'd like to let this while loop going on until I decide to stop it!

c++ Windows UTF16 L String constant

In C++ there is the following statement
wstring tester = L"Работа Центра";
we set the console output
int res = _setmode( _fileno(stdout), _O_U16TEXT);
then we try
wcout << "tester " << tester << endl << flush;
and we get on the console...
tester D D°D±D_Ñ,D° D▌DµD½Ñ,Ñ?D°
So trying to figure out what is happening here instead of getting the proper output.
Is this a code page problem?