Re: atoi
From: Joseph M. Newcomer (newcomer_at_flounder.com)
Date: 02/17/04
- Next message: Marco: "I want to make the line twinkling, but why the line can not redraw?"
- Previous message: Trevor: "Re: mmc - load node snap-in from a dll"
- In reply to: John Nash: "atoi"
- Messages sorted by: [ date ] [ thread ]
Date: Tue, 17 Feb 2004 12:59:58 -0500
Yep. That;'s how atoi is defined to work. It stops converting at the first non-numeric
character (excluding a hyphen for minus).
There are several alternative approaches, depending on how fussy you want to be and what
details you want to report.
The least reliable method is to just check to see that only digits (and perhaps a sign)
are in the string:
for(int i = 0; i < s.GetLength(); i++)
if(tcschr(_T("0123456789-"), s[i]) == NULL)
{ /* report error */
} /* report error */
But if you want to allow spaces in the string, it can't tell the difference between _12_,
12_, and _1_2 or 1__2 (where I'm using _ to show a visible space here). You can apply
operations like TrimLeft and TrimRight to remove leading and trailing spaces so then if
any spaces still exist, they are internal, but then the above also allows -12, 1-2, and
12-. So you can add a test that after the trimleft and trimright, you look at the first
character; if it is -, you skip it, and remove - from the test string, e.g.,
if( (i == 0 && s[i] == '-') ||
tcschr(_T("0123456789", s[i]) != NULL)
{ /* ok */
} /* ok */
else
{ /* error */
} /* error */
The next technique is that you could use strtol or strtoul, which take a pointer which
points to the character which terminated the scan. If it is not the NUL character, or a
space, comma, or whatever else you choose, you can report an error. These functions ignore
leading spaces but stop on trailing space, so would not detect "___1_23" as being illegal;
it would return 1 and the terminating character would be space. In this case, if you use
TrimLeft and TrimRight, then spaces would be internal and illegal.
Or, you could write a simple FSM parser of your own.
typedef enum {STATE_LEADING_WHITESPACE, STATE_DIGITS} ParseState;
ParseState state = STATE_LEADING;
WhateverIntTypeYouWant n = 0;
for(int i = 0; i < s.GetLength(); i++)
{ /* fsm */
switch(MAKELONG(state, s[i]))
{ /* state machine */
case MAKELONG(STATE_LEADING_WHITESPACE, _T(' ')):
case MAKELONG(STATE_LEADING_WHITESPACE, _T('\t')):
continue;
case MAKELONG(STATE_LEADING_WHITESPACE, _T('-')):
state = STATE_DIGITS;
continue;
case MAKELONG(STATE_LEADING_WHITESPACE(_T('0')):
... write other cases here
case MAKELONG(STATE_LEADING_WHITESPACE(_T('9')):
state = STATE_DIGITS;
continue;
case MAKELONG(STATE_DIGITS, _T('0')):
...
case MAKELONG(STATE_DIGITS,_T('9')):
continue;
default:
...syntax error report here
return false;
} /* state machine */
} /* fsm */
n = _ttoi(s);
... deal with value
return true;
Of course, if the string was in an input edit box, the simplest method is to never let
illegal characters be typed. An example of this is my numeric edit control on my MVP Tips
site, which allows you to type in a floating-point number and know it is syntactically
correct.
joe
On Tue, 17 Feb 2004 11:24:51 +0100, "John Nash" <laasunde@<remove>online.no> wrote:
>Hello,
>
>Im trying to convert a couple of cstring varaible to int using atoi.
>I do have one small problem though,
>
> CString integer = "0";
> CString str = "a";
>
> int x = atoi(integer);
> int y = atoi(str);
>
>Both the variable integer and str will both be converted into 0 (zero) when
>using atoi.
>
>This makes it a bit difficult for me to troubleshoot. I'd like to give an
>error message if a variable contains characters.
>
>
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
- Next message: Marco: "I want to make the line twinkling, but why the line can not redraw?"
- Previous message: Trevor: "Re: mmc - load node snap-in from a dll"
- In reply to: John Nash: "atoi"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|