mersenneforum.org  

Go Back   mersenneforum.org > Extra Stuff > Programming

Reply
 
Thread Tools
Old 2007-11-06, 08:32   #1
ixfd64
Bemusing Prompter
 
ixfd64's Avatar
 
"Danny"
Dec 2002
California

246610 Posts
Default 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
ixfd64 is offline   Reply With Quote
Old 2007-11-06, 08:45   #2
Chris Card
 
Chris Card's Avatar
 
Aug 2004

2×5×13 Posts
Default

Quote:
Originally Posted by ixfd64 View Post
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.
How about this?
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
Chris Card is offline   Reply With Quote
Old 2007-11-07, 01:27   #3
ColdFury
 
ColdFury's Avatar
 
Aug 2002

14016 Posts
Default

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);
}
ColdFury is offline   Reply With Quote
Old 2008-02-29, 18:29   #4
ShiningArcanine
 
ShiningArcanine's Avatar
 
Dec 2005

10111002 Posts
Default

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
ShiningArcanine is offline   Reply With Quote
Old 2008-02-29, 19:30   #5
ewmayer
2ω=0
 
ewmayer's Avatar
 
Sep 2002
Repรบblica de California

24·733 Posts
Default

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;
}
ewmayer is offline   Reply With Quote
Old 2008-03-01, 10:00   #6
xilman
Bamboozled!
 
xilman's Avatar
 
"๐’‰บ๐’ŒŒ๐’‡ท๐’†ท๐’€ญ"
May 2003
Down not across

23×5×283 Posts
Default

Quote:
Originally Posted by ewmayer View Post
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
xilman is offline   Reply With Quote
Old 2008-03-01, 10:16   #7
R. Gerbicz
 
R. Gerbicz's Avatar
 
"Robert Gerbicz"
Oct 2005
Hungary

25×72 Posts
Default

A solution for the problem in c. This also handle the case where there are trailing spaces in the input.
Code:
#include <stdio.h>
#include <string.h>


int nonnegative_integer(char *w)  {
// return by 1 if w is a nonnegative integer, 0 otherwise
    int i=0,len=strlen(w);
    
    while((i<len)&&(w[i]==' '))  i++;
    if(i==len)  return 0;
    
    if(w[i]=='+')  i++;
    if((i==len)||(w[i]<'0')||(w[i]>'9'))  return 0;
    
    while((i<len)&&(w[i]>='0')&&(w[i]<='9'))  i++;
    while((i<len)&&(w[i]==' '))  i++;
    
    if(i<len)  return 0;
    return 1;
}


int main()  {
    
    char w[1024];
    
    gets(w);
    printf("%d\n",nonnegative_integer(w));
    
    return 0;
}

Last fiddled with by R. Gerbicz on 2008-03-01 at 10:17
R. Gerbicz is offline   Reply With Quote
Old 2008-03-01, 10:17   #8
retina
Undefined
 
retina's Avatar
 
"The unspeakable one"
Jun 2006
My evil lair

193C16 Posts
Default

Quote:
Originally Posted by ewmayer View Post
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].
retina is online now   Reply With Quote
Old 2008-03-02, 03:22   #9
ewmayer
2ω=0
 
ewmayer's Avatar
 
Sep 2002
Repรบblica de California

24×733 Posts
Default

Quote:
Originally Posted by xilman View Post
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.
ewmayer is offline   Reply With Quote
Old 2008-03-02, 15:10   #10
wblipp
 
wblipp's Avatar
 
"William"
May 2003
New Haven

2,371 Posts
Default

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
wblipp is offline   Reply With Quote
Old 2008-03-04, 15:35   #11
xilman
Bamboozled!
 
xilman's Avatar
 
"๐’‰บ๐’ŒŒ๐’‡ท๐’†ท๐’€ญ"
May 2003
Down not across

23×5×283 Posts
Default

Quote:
Originally Posted by ewmayer View Post
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
xilman is offline   Reply With Quote
Reply

Thread Tools


Similar Threads
Thread Thread Starter Forum Replies Last Post
Days to-go in computer details is a negative number dufrenbk Information & Answers 3 2013-03-23 22:02
square root equal to a negative LaurV Homework Help 34 2013-03-03 09:35
modulo division with negative power ? smslca Math 40 2012-01-10 12:02
Testing if expression over the reals is negative CRGreathouse Math 3 2009-04-05 19:12
rational powers of negative one 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

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.

This forum has received and complied with 0 (zero) government requests for information.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation.
A copy of the license is included in the FAQ.

โ‰  ยฑ โˆ“ รท ร— ยท โˆ’ โˆš โ€ฐ โŠ— โŠ• โŠ– โŠ˜ โŠ™ โ‰ค โ‰ฅ โ‰ฆ โ‰ง โ‰จ โ‰ฉ โ‰บ โ‰ป โ‰ผ โ‰ฝ โŠ โŠ โŠ‘ โŠ’ ยฒ ยณ ยฐ
โˆ  โˆŸ ยฐ โ‰… ~ โ€– โŸ‚ โซ›
โ‰ก โ‰œ โ‰ˆ โˆ โˆž โ‰ช โ‰ซ โŒŠโŒ‹ โŒˆโŒ‰ โˆ˜ โˆ โˆ โˆ‘ โˆง โˆจ โˆฉ โˆช โจ€ โŠ• โŠ— ๐–• ๐–– ๐–— โŠฒ โŠณ
โˆ… โˆ– โˆ โ†ฆ โ†ฃ โˆฉ โˆช โŠ† โŠ‚ โŠ„ โŠŠ โŠ‡ โŠƒ โŠ… โŠ‹ โŠ– โˆˆ โˆ‰ โˆ‹ โˆŒ โ„• โ„ค โ„š โ„ โ„‚ โ„ต โ„ถ โ„ท โ„ธ ๐“Ÿ
ยฌ โˆจ โˆง โŠ• โ†’ โ† โ‡’ โ‡ โ‡” โˆ€ โˆƒ โˆ„ โˆด โˆต โŠค โŠฅ โŠข โŠจ โซค โŠฃ โ€ฆ โ‹ฏ โ‹ฎ โ‹ฐ โ‹ฑ
โˆซ โˆฌ โˆญ โˆฎ โˆฏ โˆฐ โˆ‡ โˆ† ฮด โˆ‚ โ„ฑ โ„’ โ„“
๐›ข๐›ผ ๐›ฃ๐›ฝ ๐›ค๐›พ ๐›ฅ๐›ฟ ๐›ฆ๐œ€๐œ– ๐›ง๐œ ๐›จ๐œ‚ ๐›ฉ๐œƒ๐œ— ๐›ช๐œ„ ๐›ซ๐œ… ๐›ฌ๐œ† ๐›ญ๐œ‡ ๐›ฎ๐œˆ ๐›ฏ๐œ‰ ๐›ฐ๐œŠ ๐›ฑ๐œ‹ ๐›ฒ๐œŒ ๐›ด๐œŽ๐œ ๐›ต๐œ ๐›ถ๐œ ๐›ท๐œ™๐œ‘ ๐›ธ๐œ’ ๐›น๐œ“ ๐›บ๐œ”