mersenneforum.org need help with C++ code (non-negative integers)
 Register FAQ Search Today's Posts Mark Forums Read

 2007-11-06, 08:32 #1 ixfd64 Bemusing Prompter     "Danny" Dec 2002 California 246610 Posts need help with C++ code (non-negative integers) I'm writing some code that takes in a string and returns true if it represents a non-negative integer, false otherwise. Code: // non-negative integer validation bool isNonNegInt(string str) { int i = 0; while (i++ < str.length()) { if (!isdigit(str[i])) { return false; } else { return true; } } } However, it doesn't work correctly. It returns the correct result only if the input is two or more characters long. Also, isdigit() always returns 4 for some reason. Can anyone help? Thanks. Update: never mind, I got it to work. Here's my new code. Code: bool isNonNegInt(string str) { bool v = false; for (int i = 0; i < str.length(); i++) { if (!isdigit(str[i])) { return false; break; } else { v = true; } } return v; } Last fiddled with by ixfd64 on 2007-11-06 at 08:45
2007-11-06, 08:45   #2
Chris Card

Aug 2004

2×5×13 Posts

Quote:
 Originally Posted by ixfd64 I'm writing some code that takes in a string and returns true if it represents a non-negative integer, false otherwise. Code: // non-negative integer validation bool isNonNegInt(string str) { int i = 0; while (i++ < str.length()) { if (!isdigit(str[i])) { return false; } else { return true; } } } However, it doesn't work correctly. It returns the correct result only if the input is two or more characters long. Also, isdigit() always returns 4 for some reason. Can anyone help? Thanks.
Code:
bool isNonNegInt(const string& str)
{
if (str.empty())
return false;

for (size_t i = 0; i < str.length(); ++i)
{
if (!isdigit(str[i]))
return false;
}

return true;
}
Chris

 2007-11-07, 01:27 #3 ColdFury     Aug 2002 14016 Posts Does this have to work for strings representing arbitrarily large numbers? If not: Code: bool isNonNegInt(string str) { istringstream iss(str); int x; if (!(iss >> x)) return false; return (x < 0); }
 2008-02-29, 18:29 #4 ShiningArcanine     Dec 2005 10111002 Posts Why not do this: Code: bool isNonNegInt(string str) { return (atoi(str.c_str) <= 0) ? false : true; } Last fiddled with by ShiningArcanine on 2008-02-29 at 18:30 Reason: Added CODE tags
 2008-02-29, 19:30 #5 ewmayer ∂2ω=0     Sep 2002 República de California 24·733 Posts None of the simple-loop-over-chars posts address the issue of dealing with leading white space. ShiningArcanine's post neatly handles that via the atoi() C library function, but that can fail if the input overflows a 32-bit signed-int field, and atoi() stops parsing when it hits a non-numeric, i.e. the code would incorrectly flag e.g. 3.14159 as a nonnegative integer. The following small modification takes care of such occurrences: Code: bool isNonNegInt(string str) { int i = atoi(str.c_str()); double x = atof(str.c_str()); return ((i != x) || i <= 0) ? false : true; } ...but this still fails to properly deal with inputs that overflow a 32-bit field, e.g. incorrectly flagging 314159265358979323846264 as "not a nonnegative int". Here's a code snippet that deals with all of these issues, plus the possibility of a leading '+' sign, although at most one of these is allowed and if it occurs it must immediately precede a numeric char, e.g. "++2" and "+ 4" would both get flagged "false". Also e.g. "31459." gets flagged as non-int, although if one wanted to treat such cases as "true" they could also easily be special-cased: Code: bool isNonNegInt(string str) { int i; char c; for(i = 0; i < str.size(); ++i) { c = str[i]; if(isspace(c)) continue; if( c == '+' && isdigit(str[i+1])) continue; if(isdigit(c)) continue; return false; } return true; }
2008-03-01, 10:00   #6
xilman
Bamboozled!

"𒉺𒌌𒇷𒆷𒀭"
May 2003
Down not across

23×5×283 Posts

Quote:
 Originally Posted by ewmayer None of the simple-loop-over-chars posts address the issue of dealing with leading white space. ShiningArcanine's post neatly handles that via the atoi() C library function, but that can fail if the input overflows a 32-bit signed-int field, and atoi() stops parsing when it hits a non-numeric, i.e. the code would incorrectly flag e.g. 3.14159 as a nonnegative integer. The following small modification takes care of such occurrences: Code: bool isNonNegInt(string str) { int i = atoi(str.c_str()); double x = atof(str.c_str()); return ((i != x) || i <= 0) ? false : true; } ...but this still fails to properly deal with inputs that overflow a 32-bit field, e.g. incorrectly flagging 314159265358979323846264 as "not a nonnegative int". Here's a code snippet that deals with all of these issues, plus the possibility of a leading '+' sign, although at most one of these is allowed and if it occurs it must immediately precede a numeric char, e.g. "++2" and "+ 4" would both get flagged "false". Also e.g. "31459." gets flagged as non-int, although if one wanted to treat such cases as "true" they could also easily be special-cased: Code: bool isNonNegInt(string str) { int i; char c; for(i = 0; i < str.size(); ++i) { c = str[i]; if(isspace(c)) continue; if( c == '+' && isdigit(str[i+1])) continue; if(isdigit(c)) continue; return false; } return true; }
And what happens if the string is "+"?

Paul

Last fiddled with by xilman on 2008-03-01 at 10:02

 2008-03-01, 10:16 #7 R. Gerbicz     "Robert Gerbicz" Oct 2005 Hungary 25×72 Posts A solution for the problem in c. This also handle the case where there are trailing spaces in the input. Code: #include #include int nonnegative_integer(char *w) { // return by 1 if w is a nonnegative integer, 0 otherwise int i=0,len=strlen(w); while((i'9')) return 0; while((i='0')&&(w[i]<='9')) i++; while((i
2008-03-01, 10:17   #8
retina
Undefined

"The unspeakable one"
Jun 2006
My evil lair

193C16 Posts

Quote:
 Originally Posted by ewmayer Code: bool isNonNegInt(string str) { int i; char c; for(i = 0; i < str.size(); ++i) { c = str[i]; if(isspace(c)) continue; if( c == '+' && isdigit(str[i+1])) continue; if(isdigit(c)) continue; return false; } return true; }`
What happens is the input is "+1 3+1"?

I think an ideal procedure would be:
1. Trim leading and trailing spaces.
2. If the first character is "+" then trim it.
3. Check that all remaining characters are digits [0-9].

2008-03-02, 03:22   #9
ewmayer
2ω=0

Sep 2002
República de California

24×733 Posts

Quote:
 Originally Posted by xilman And what happens if the string is "+"?
I also realized soon after posting that e.g. "0" would be improperly flagged as positive, but figured some of you clever folks would catch that. One could combine both the atoi()-based and string-parse method to handle that - let atoi parse the leading few nonzero digits, and go igit-by-digit on the remainder. But there's probably some inputs that break that as well.

This is typical of these types of utility routines - one spends > 90% of one's time writing code to handle why-would-anyone-want-to-do-it-that-way corner cases.

 2008-03-02, 15:10 #10 wblipp     "William" May 2003 New Haven 2,371 Posts If you have a regular expression library such as regex.h, you could use that. The regular expression most people in this thread have used is zero or more spaces zero or 1 plus signs 1 or more digits zero or more spaces.I think this is " *\+\{0,1\}[0-9]+ *" with some minor changes if you want to allow whitespace instead of blanks for the leading and trailing strings. http://en.wikipedia.org/wiki/Regular_expression Last fiddled with by wblipp on 2008-03-02 at 15:11 Reason: spelling
2008-03-04, 15:35   #11
xilman
Bamboozled!

"𒉺𒌌𒇷𒆷𒀭"
May 2003
Down not across

23×5×283 Posts

Quote:
 Originally Posted by ewmayer I also realized soon after posting that e.g. "0" would be improperly flagged as positive, but figured some of you clever folks would catch that. One could combine both the atoi()-based and string-parse method to handle that - let atoi parse the leading few nonzero digits, and go igit-by-digit on the remainder. But there's probably some inputs that break that as well. This is typical of these types of utility routines - one spends > 90% of one's time writing code to handle why-would-anyone-want-to-do-it-that-way corner cases.
If one defines "positive" to be non-negative, you're ok with your edge case. The bug I spotted woud cause a core dump, if you're lucky, and a silent guess at the positivity if you're not.

Paul

 Similar Threads Thread Thread Starter Forum Replies Last Post dufrenbk Information & Answers 3 2013-03-23 22:02 LaurV Homework Help 34 2013-03-03 09:35 smslca Math 40 2012-01-10 12:02 CRGreathouse Math 3 2009-04-05 19:12 nibble4bits Math 5 2008-01-08 04:58

All times are UTC. The time now is 18:31.

Fri May 27 18:31:40 UTC 2022 up 43 days, 16:32, 0 users, load averages: 1.15, 1.60, 1.72