cin failure on windows?

I've been programming for a while, but I am by no means a C++ master.
I have been bugged about this for a while. Here is a simple program that shows a major failure in the implementation of cin. I don't know if it happens on linux or Macintosh, but it always happens under Windows, whether I am using visual c++ express or a commercial version of Visual Studio.
I refuse to switch to the GCC because I am too attached to Microsoft's IDE and don't want to change it.
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std;
int main()
{
  int x = 0;
  do
  {
    cout << "Please enter a number other than 0.";
    cin >> x;
  }while(x ==0);
}

Enter a non-int(i.e. the string "one") and it fails terribly. How can I fix it to always clear the buffer in cin between calls to operator>> ?
Thanks!
Last edited on
closed account (o1vk4iN6)
Change is good! To refuse to do so is to be lazy and refuse innovation.

 
if(!cin >> x) break;
As far as "refusing innovation" by refusing to switch to GCC, I don't really see anything good in the GreatCommunistCompiler. Besides, this quote was said by someone who seems to be unfamiliar with the c++ order of operations. The not operators(! and ~) are processed before the bit shift operators (<< and >>), thus when !cin>>x is called the return value of !cin is sent the << message and always fails without getting input.

Of course he also failed to correct one of my own mistakes too, so he may have just been tired. That would also explain why he promoted the GCC like an ignorant fanboy.

I guess I can just use a string buffer and getline(cin, buffer) and send that to a istringstream to search for numeric characters and use that as input, but I prefer to work on things using the standard library if I can, and not focus on fixing errors in work that should in theory already be done for me.
Last edited on
closed account (o1vk4iN6)
I simply stated that to refuse change is to refuse innovation, to innovate is to change. It was only your ignorance that made a connection to GCC.
It is not a "failure in the implementation of cin", it is standard-mandated behavior. Your program is explicitly written to enter an endless loop if the user enters a non-integer.

As for solving it, it depends on what your desired behavior is in case of such input. If you just want to quit, then modify the loop test to be while(cin && x == 0)
I have decided that I will use string, istringstream, and my own custom userinput objects to get the necessary input and not have it fail. If the value of x is 0, I ask the user to try again.

@cubby Why is such a behavior mandated? Is there any way to recover from an input error without parsing it char-by-char for the input I want?

@xerzi not all change is innovation, but all innovation is change. You have your innovation-change hierarchy mixed up. Surely any programmer with object-oriented experience would understand the simple law of logic if a "thing 2" is a "thing 1", a "thing1" could be but is not necessarily a "thing 2". After all, is switching to Windows ME from Windows 7 an innovation? I certainly think not! I don't look at the fact that it is a change to determine if it is an innovation; I look at the change itself - in this case, the change from the Microsoft compiler to the GCC.
Last edited on
would you consider using a class designed for windows - I called it konio - it has an extern instance of it called kio.

if you include this class in stdafx.h or in all places where cout and cin is needed you could simply replace your cout and cin calls with kio.

for example:

1
2
int x;
kio >> x;


will only accept numerical values from keyboard or if x was a double it would only accept a proper real number.

will something like this be helpfull to you?
this class also has methods for moving cursor on screen (gotoxy) changing background or foreground color, turning cursor on/off, clearing the screen, ...

you could strip out these other methods quite easily from class if not needed - the code is code simple and straightforward.
closed account (o1vk4iN6)
@puzlanzen
You can't know if you've never tried thus there is no change.
Last edited on
@OP:
You try to read and fail, that puts the object in an invalid state (zombie)
If you operate on a zombie, you can't have a valid result.
That is useful if you want to know if you fail.

If you want to recover from the failure cin.clear()
However you never read anything so the input is still in the buffer
cin.ignore( std::numeric_limits< std::streamsize >::max(), '\n' ); to avoid that.

There is another problem.
$ ./a.out < input.txt 
the input will fail on EOF, if you keep clearing -> infinite loop.
@ne555 and SIK
It's good to know there are some alternatives to cin/cout and some ways to recover cin that should work.

Where can I find this konio class? Is it in one of the headers provided with Visual Studio, or is it in another library?

@xerzi I have tried the GCC. Here's my life story as of when I became a programmer:

After I learned to program Java, I decided to learn other more powerful languages like C++. I am glad to have an alternative to the GCC on Windows.

Before I got this computer I programmed on my family's mac (running OSX leopard), which FYI uses the GCC. The programming was okay, but I was not able to get any work done because I had a one hour per day time limit on my family's mac, and it takes me a while for me to gain momentum in programming. In addition to that, I wanted to make rogue-like adventure games for terminal(i.e. ASCII-art sprites), and the help forums weren't good at helping me understand how to get keyboard input from the console.

The first OS I installed on this computer was Ubuntu 10.4, quickly followed by 10.10
The GCC and all the IDEs I used were too complicated. Thus, I found myself hardly able to program because I was continually either re-configuring my IDE or changing a makefile or installing an update for the OS.

I'm just glad I have Windows installed now because I can teach myself C# in the environment made for learning C# by the company that developed C#. Since Visual C# express is so good as far as I care, I decided to get the other visual studio express IDEs, and they have been working perfectly for me.

If I really wanted to use the GCC, I would install Putty on this computer and use it to log into my account on my family's mac, which still runs OSX Leopard and has xCode installed with all the other developing applications. I will NOT use a third-party compiler for an OS made by a company that provides its own compiler.
Last edited on
@puzlanzen: konio is not part of vs - I created it myself. To use konio, simply add konio.h and konio.cpp to your project. You may then include konio.h in files where you wish to use it or include it in your projects stdafx.h file.

An extern instance of konio called kio is defined in konio.h. I also defined extern reference instances to kio called kin and kout.

sample of use:
1
2
3
4
5
6
7
8
9
int nAge;
double fIQ;

kio << "Enter Age: ";
kio >> nAge;

kio << "Enter IQ: " >> fIQ;

kio << "Age is: " << nAge << " and IQ is: " << fIQ;


When testing this, you will note that you will only be able to enter an integer value for nAge and only a double value for fIQ.

If you use it to read a string from the keyboard, it will return the complete string and not just the first word.

Please see posts below for source code for konio:
I have tested this on vs_9 and codeblocks (using gcc) and even works on vs_6

konio.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#ifndef konio__h
#define konio__h


#include <string>
#include <windows.h>



using namespace std;



#define BLACK           0
#define BLUE            1
#define GREEN           2
#define CYAN            3
#define RED             4
#define PURPLE          5
#define BROWN           6
#define WHITE           7
#define GRAY            8
#define LBLUE           9
#define LGREEN          10
#define LCYAN           11
#define LRED            12
#define LPURPLE         13
#define YELLOW          14
#define BWHITE          15



class konio
{
public:
   konio();
   ~konio();

   void CreateConsole();

   char GetCharInput(const string & strPrompt);
   short GetShortInput(const string & strPrompt);
   int GetIntInput(const string & strPrompt);
   double GetDblInput(const string & strPrompt);
   string GetStringInput(const string & strPrompt);

   void operator >>(char & cVal);
   void operator >>(short & sVal);
   void operator >>(int & nVal);
   void operator >>(double & fVal);
   void operator >>(string & strVal);
   void operator >>(char * szVal);

   konio & operator <<(konio & (* f)(konio &));
   konio & operator <<(char cVal);
   konio & operator <<(short sVal);
   konio & operator <<(int nVal);
   konio & operator <<(double fVal);
   konio & operator <<(const string & strVal);
   konio & operator <<(const char * szVal);


   void GetCursorPos(int & x, int & y);
   void GotoXY(int x, int y);
   void Clrscr();
   void SetForeColor(int c);
   void SetBackColor(int c);
   int GetForeColor();
   int GetBackColor();

   void GetScreenDims();

   int GetDimX() const;
   int GetDimY() const;
   void OutputXY(int x, int y, const char * szFmt, ...);

   void HideCursor(bool bHide);
   void EnableWrapping(bool bEnable);

private:
   static HANDLE        m_hConsole;
   bool                 m_bIns;
   string               m_strInput;
   unsigned int         m_nPos;
   int                  m_nPosX;
   int                  m_nPosY;
   int                  m_nDimX;
   int                  m_nDimY;



   void _Init();

   string _GetInput(const string & strPrompt, bool bIntChars, bool bIsReal, unsigned int nCount);
   void _ApplyInputChar(char ch, bool bIntChars, bool bIsReal, unsigned int nCount);
   bool _ApplyReturn(unsigned int nCount);
   void _ApplySpecialKey();
   void _ApplyBackSpace();
   void _ApplyDelete();

   void _ApplyCursorPos();
   void _ApplyGoLeft();
   void _ApplyGoRight();
   void _ApplyInsert();

   void _OutputRemainingText(int nPos=-1);
   bool _ValidateInput(char ch, bool bIntChars, bool bIsReal);
};


konio & endl(konio & s);


extern konio kio;
extern konio &kin;
extern konio &kout;


#endif //konio__h
konio.cpp (1st half - other post seems too long)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
#include "konio.h"
#include <conio.h>
#include <FCNTL.h>
#include <stdlib.h>
#include <stdio.h>
#include <io.h>
#include <iostream>


HANDLE konio::m_hConsole = GetStdHandle(STD_OUTPUT_HANDLE);


konio kio;
konio &kin = kio;
konio &kout = kio;



konio::konio()
{
   _Init();
}


konio::~konio()
{
   _Init();
}


void konio::CreateConsole()
{
   BOOL bSuccess = AllocConsole();
   if (!bSuccess)    return;

   HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
   int hCrt = _open_osfhandle((long) handle_out, _O_TEXT);
   FILE* hf_out = _fdopen(hCrt, "w");
   setvbuf(hf_out, NULL, _IONBF, 1);
   *stdout = *hf_out;

   HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE);
   hCrt = _open_osfhandle((long) handle_in, _O_TEXT);
   FILE* hf_in = _fdopen(hCrt, "r");
   setvbuf(hf_in, NULL, _IONBF, 128);
   *stdin = *hf_in;

   _Init();
}


char konio::GetCharInput(const string & strPrompt)
{
   return _GetInput(strPrompt, false, false, 1)[0];
}


short konio::GetShortInput(const string & strPrompt)
{
   return atoi(_GetInput(strPrompt, true, false, 6).c_str());
}


int konio::GetIntInput(const string & strPrompt)
{
   return atoi(_GetInput(strPrompt, true, false, 10).c_str());
}


double konio::GetDblInput(const string & strPrompt)
{
   return atof(_GetInput(strPrompt, true, true, 22).c_str());
}


string konio::GetStringInput(const string & strPrompt)
{
   return _GetInput(strPrompt, false, false, 0);
}


void konio::operator >>(char & cVal)
{
   cVal = GetCharInput("");
}


void konio::operator >>(short & sVal)
{
   sVal = GetShortInput("");
}


void konio::operator >>(int & nVal)
{
   nVal = GetIntInput("");
}


void konio::operator >>(double & fVal)
{
   fVal = GetDblInput("");
}


void konio::operator >>(string & strVal)
{
   strVal = GetStringInput("");
}


void konio::operator >>(char * szVal)
{
   strcpy(szVal, GetStringInput("").c_str());
}


konio & konio::operator <<(konio & (* f)(konio &))
{
   return f(*this);
}


konio & konio::operator <<(char cVal)
{
   printf("%c", cVal);
   return *this;
}


konio & konio::operator <<(short sVal)
{
   printf("%d", sVal);
   return *this;
}


konio & konio::operator <<(int nVal)
{
   printf("%d", nVal);
   return *this;
}


konio & konio::operator <<(double fVal)
{
   printf("%f", fVal);
   return *this;
}


konio & konio::operator <<(const string & strVal)
{
   printf("%s", strVal.c_str());
   return *this;
}


konio & konio::operator <<(const char * szVal)
{
   printf("%s", szVal);
   return *this;
}


void konio::GetScreenDims()
{
   CONSOLE_SCREEN_BUFFER_INFO csbi;
   GetConsoleScreenBufferInfo(m_hConsole, &csbi);

   m_nDimX = csbi.srWindow.Right - csbi.srWindow.Left + 1;
   m_nDimY = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
   m_nPosX = csbi.dwCursorPosition.X;
   m_nPosY = csbi.dwCursorPosition.Y;
}


void konio::GetCursorPos(int & x, int & y)
{
   CONSOLE_SCREEN_BUFFER_INFO csbi;
   GetConsoleScreenBufferInfo(m_hConsole, &csbi);

   x = csbi.dwCursorPosition.X;
   y = csbi.dwCursorPosition.Y;
}


void konio::GotoXY(int x, int y)
{
   COORD coord;
   coord.X = x;
   coord.Y = y;
   SetConsoleCursorPosition(m_hConsole, coord);
}


void konio::Clrscr()
{
   cout.flush();

   DWORD dw;
   CONSOLE_SCREEN_BUFFER_INFO csbi;
   COORD coord = {0, 0};

   GetConsoleScreenBufferInfo(m_hConsole, &csbi);
   DWORD dwSize = csbi.dwSize.X * csbi.dwSize.Y;
   FillConsoleOutputCharacter(m_hConsole, ' ', dwSize, coord, &dw);
   FillConsoleOutputAttribute(m_hConsole, csbi.wAttributes, dwSize,  coord, &dw);
   SetConsoleCursorPosition(m_hConsole, coord);
}



void konio::SetForeColor(int c)
{
   WORD wAttrib = 0;
   CONSOLE_SCREEN_BUFFER_INFO csbi;
   GetConsoleScreenBufferInfo(m_hConsole, &csbi);

   wAttrib = csbi.wAttributes;
   wAttrib &= ~(FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY);
   if (c & 1)     wAttrib |= FOREGROUND_BLUE;
   if (c & 2)     wAttrib |= FOREGROUND_GREEN;
   if (c & 4)     wAttrib |= FOREGROUND_RED;
   if (c & 8)     wAttrib |= FOREGROUND_INTENSITY;
   SetConsoleTextAttribute(m_hConsole, wAttrib);
}


void konio::SetBackColor(int c)
{
   WORD wAttrib = 0;
   CONSOLE_SCREEN_BUFFER_INFO csbi;
   GetConsoleScreenBufferInfo(m_hConsole, &csbi);

   wAttrib = csbi.wAttributes;
   wAttrib &= ~(BACKGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_RED|BACKGROUND_INTENSITY);
   if (c & 1)     wAttrib |= BACKGROUND_BLUE;
   if (c & 2)     wAttrib |= BACKGROUND_GREEN;
   if (c & 4)     wAttrib |= BACKGROUND_RED;
   if (c & 8)     wAttrib |= BACKGROUND_INTENSITY;
   SetConsoleTextAttribute(m_hConsole, wAttrib);
}


int konio::GetForeColor()
{
   int c = 0;
   WORD wAttrib = 0;
   CONSOLE_SCREEN_BUFFER_INFO csbi;
   GetConsoleScreenBufferInfo(m_hConsole, &csbi);

   wAttrib = csbi.wAttributes;
   if (wAttrib & FOREGROUND_BLUE)        c |= 1;
   if (wAttrib & FOREGROUND_GREEN)       c |= 2;
   if (wAttrib & FOREGROUND_RED)         c |= 4;
   if (wAttrib & FOREGROUND_INTENSITY)   c |= 8;

   return c;
}


int konio::GetBackColor()
{
   int c = 0;
   WORD wAttrib = 0;
   CONSOLE_SCREEN_BUFFER_INFO csbi;
   GetConsoleScreenBufferInfo(m_hConsole, &csbi);

   wAttrib = csbi.wAttributes;
   if (wAttrib & BACKGROUND_BLUE)        c |= 1;
   if (wAttrib & BACKGROUND_GREEN)       c |= 2;
   if (wAttrib & BACKGROUND_RED)         c |= 4;
   if (wAttrib & BACKGROUND_INTENSITY)   c |= 8;

   return c;
}


int konio::GetDimX() const
{
   return m_nDimX;
}


int konio::GetDimY() const
{
   return m_nDimY;
}


void konio::OutputXY(int x, int y, const char * szFmt, ...)
{
   GotoXY(x, y);

   va_list vl;
   va_start(vl, szFmt);
   vprintf(szFmt, vl);
   va_end(vl);
}


void konio::HideCursor(bool bHide)
{
   CONSOLE_CURSOR_INFO ci;
   ci.dwSize = 1;
   ci.bVisible = bHide ? FALSE : TRUE;
   SetConsoleCursorInfo(m_hConsole, &ci);
}


void konio::EnableWrapping(bool bEnable)
{
   DWORD dwMode;
   GetConsoleMode(m_hConsole, &dwMode);
   dwMode &= bEnable ? ENABLE_WRAP_AT_EOL_OUTPUT : ~ENABLE_WRAP_AT_EOL_OUTPUT;
   SetConsoleMode(m_hConsole, dwMode);
}
konio.cpp (2nd half - private methods)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
void konio::_Init()
{
   m_nPos = 0;
   m_bIns = true;
   m_strInput.erase();

   GetScreenDims();
}


void konio::_ApplySpecialKey()
{
   char ch = (char)_getch();

   switch (ch)
   {
      case 75:    _ApplyGoLeft(); break;
      case 77:    _ApplyGoRight(); break;
      case 82:    _ApplyInsert(); break;
      case 83:    _ApplyDelete(); break;
   }
}


void konio::_ApplyBackSpace()
{
   if (m_nPos < 1)      return;

   m_nPos--;
   m_strInput.erase(m_nPos, 1);

   _OutputRemainingText();
}


void konio::_ApplyDelete()
{
   if (m_nPos >= m_strInput.size())     return;
   m_strInput.erase(m_nPos, 1);
   _OutputRemainingText();
}


string konio::_GetInput(const string & strPrompt, bool bIntChars, bool bIsReal, unsigned int nCount)
{
   printf(strPrompt.c_str());
   _Init();

   while (true)
   {
      char ch = (char)_getch();

      switch (ch)
      {
         case 13:    if (_ApplyReturn(nCount))   return m_strInput;
                     break;

         case 0:
         case -32:   _ApplySpecialKey(); break;
         case 8:     _ApplyBackSpace(); break;
         default:    _ApplyInputChar(ch, bIntChars, bIsReal, nCount);
      }
   }
}


void konio::_ApplyInputChar(char ch, bool bIntChars, bool bIsReal, unsigned int nCount)
{
   if (nCount && m_strInput.size()>=nCount)                    return;
   if (!_ValidateInput(ch, bIntChars, bIsReal))                return;

   unsigned int nPos = m_nPos;
   m_nPos++;

   if (nPos >= m_strInput.size())
   {
      m_strInput += ch;
      printf("%c", ch);
   }
   else if (!m_bIns)
   {
      m_strInput[nPos] = ch;
      printf("%c", ch);
   }
   else
   {
      char szCh[2];
      szCh[0] = ch;
      szCh[1] = 0;
      m_strInput.insert(nPos, szCh);
      _OutputRemainingText(nPos);
   }
}


bool konio::_ApplyReturn(unsigned int nCount)
{
   if (nCount==1 && !m_strInput.size())    return false;

   m_nPos = m_strInput.size() + 1;
   _ApplyCursorPos();
   printf("\n");
   return true;
}


void konio::_ApplyCursorPos()
{
   int x = (m_nPosX + m_nPos) % m_nDimX;
   int y = (m_nPosX + m_nPos) / m_nDimX + m_nPosY;

   GotoXY(x, y);
}


void konio::_ApplyGoLeft()
{
   if (m_nPos < 1)      return;
   m_nPos--;

   _ApplyCursorPos();
}


void konio::_ApplyGoRight()
{
   if (m_nPos >= m_strInput.size())  return;
   m_nPos++;

   _ApplyCursorPos();
}


void konio::_ApplyInsert()
{
   m_bIns = !m_bIns;
}


void konio::_OutputRemainingText(int nPos)
{
   if (nPos == -1)      nPos = m_nPos;

   int x = (m_nPosX + nPos) % m_nDimX;
   int y = (m_nPosX + nPos) / m_nDimX + m_nPosY;

   OutputXY(x, y, "%s ", &m_strInput.c_str()[nPos]);
   _ApplyCursorPos();
}


bool konio::_ValidateInput(char ch, bool bIntChars, bool bIsReal)
{
   if (!bIntChars)      return true;
   if (ch == '-')       return !m_nPos && m_strInput.find('-')==std::string::npos;
   if (ch == '.')       return bIsReal && m_strInput.find('.')==std::string::npos;

   return (ch >= '0'  && ch <= '9');
}


konio & endl(konio & s)
{
   return s << '\n';
}
Interesting. This is really developed - even more developed than the simple object I cooked up myself for input without the bugs or errors. It also looks powerful, but some of it, i.e. the color macros, looks sloppy and easily changed with an enumerated type.

To think I am only looking at the header right now...


What sort of license is this under, or are you putting this in the public domain? Based on how you said I should include the header and the source in my projects, I doubt you are putting it under the GPL or LGPL. If I can improve it, should I show you my improvements? May I compile this into a DLL for use with my future projects?

Seriously, I don't like the GPL very much for my own reasons, but I can't just take a resource like this for free! To me this is the time-saving work of genius that I would have taken weeks to type up and debug, even if I had started with the header file.
Last edited on
@puzlanzen: Thank you for your kind words. You may use this code absolutely free or charge in which ever manner you see fit.

Your idea on using a enum to define the colors is much better than the macros I have - I will try that instead in my dll version - thank you for sharing this and yes - please do share any future improvements you may come up with.

Please note that I have ripped this class out of one of my personal libries so had to change a few things in the versions I sent to you - thus there may be a bug or two - if you do come across any, please don't hesitate to mail me on this forum to my private messages and I will try to address it for you.

May we speak again soon.
small update to _ValidateInput method to correctly validate application of minus sign:

1
2
3
4
5
6
7
8
9
10
11
12
13
bool konio::_ValidateInput(char ch, bool bIntChars, bool bIsReal)
{
   unsigned int nPosMinus = m_strInput.find('-');

   if (!bIntChars)      return true;
   if (ch == '-')       return !m_nPos && nPosMinus==std::string::npos;
   if (ch == '.')       return bIsReal && m_strInput.find('.')==std::string::npos;

   if (nPosMinus!=std::string::npos && m_bIns && m_nPos<=nPosMinus)     return false;

   return (ch >= '0'  && ch <= '9');
}
Topic archived. No new replies allowed.