checking string if number or not

This is a discussion on checking string if number or not within the C Programming forums, part of the General Programming Boards category; I've made a function that determines if character string is a number or not.Using only isdigit(). Here is my sample ...

  1. #1
    Registered User jaro's Avatar
    Join Date
    Mar 2006
    Location
    In my Parent House
    Posts
    34

    checking string if number or not

    I've made a function that determines if character string is a number or not.Using only isdigit().

    Here is my sample code
    Code:
    #include <string.h>
    #include <stdio.h>
    #include <ctype.h>
    
    int isNumber(char str[])
    {
    	int withDecimal =0,isNegative=0 ,i=0;
    	int len = strlen(str);
    
    	for (i=0; i<len; i++)
    	{
    		if (!isdigit(str[i])) // if1
    		{
    			if (str[i] == '.')
    			{
    				if(withDecimal){
    					return 0;
    				}
    				withDecimal =1;
    			}
    			else if (str[i] == '-')
    			{
    				if(isNegative){
    					return 0;
    				}
    
    				if(i==0){
    					isNegative = 1;
    				}else{
    					return 0;
    				}
    
    			}else{
    				return 0;
    			}
    		} //end if1
    	}// end for
    	return 1;
    }
    
    int main(){
    	
    	//for testing purpose only
    	char charNum[10][15] = {
    		"100.23" ,
    		"-200.456",
    		"200..",
    		"..200",
    		"4.9.9.6",
    		"--500",
    		"500--",
    		"59-52-6",
    		"50.69-5",
    		"5000"
    	};
    
    	int cntr = 0;
    
    		for(cntr=0; cntr<10; cntr++){
    			printf("%s\t\t", charNum[cntr]);
    
    			if(isNumber(charNum[cntr])){
    				printf("is a number!\n");
    			}else{
    				printf("NOT a NUMBER!\n");
    			}
    		}
    
    }
    and here is the output
    Code:
    100.23          is a number!
    -200.456        is a number!
    200..           NOT a NUMBER!
    ..200           NOT a NUMBER!
    4.9.9.6         NOT a NUMBER!
    --500           NOT a NUMBER!
    500--           NOT a NUMBER!
    59-52-6         NOT a NUMBER!
    50.69-5         NOT a NUMBER!
    5000            is a number!
    as you can see. The function works fine.But to be on the safe side.I need to know your reaction on the function, whether it needs to improve on some aspects (memory utilization or something).

    regards,
    Jaro

  2. #2
    Registered User wintellect's Avatar
    Join Date
    Mar 2006
    Posts
    24
    Personally, I would have your function return 0 when the char is a digit and -1 on error

    ...but this is probablyon a personal thing

  3. #3
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,417
    I think "-." also passes your tests
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  4. #4
    Registered User jaro's Avatar
    Join Date
    Mar 2006
    Location
    In my Parent House
    Posts
    34
    Quote Originally Posted by Salem
    I think "-." also passes your tests

    my lame excuse behind allowing "-." because some people input number this way.
    i.e. normally we write some number in this format "-0.25" but some people will write "-.25" which mathematically speaking is the same.
    well,I hope that this reasoning is good for your taste.

    anyway, thanks for the quick feedback.and actually without your comment I would not found another two errors.Apparently the characters "-" and "." will be considered a number.

    regards,
    Jaro

  5. #5
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    I think Salem was saying if you inputted "-." only it would register as a number. An easy way out if simply to check the length of the input string. If it has a length of 1 and withDecimal or isNegative are set return 0, and if the length is 2 and withDecimal and isNegative are set return 0.

    Personally, I would have your function return 0 when the char is a digit and -1 on error

    ...but this is probablyon a personal thing
    Consider the function name, isNumber(). Now all of the standard is*() functions return nonzero if the input meets the condition and 0 if it does not. So the way the function is written is in keeping with that. Also 0 means false while nonzero means true. So a commonily used shortcut would be something like:
    Code:
    if ( isNumber("2.7818") )
    {
      // Blah
    }
    and
    Code:
    if ( !isNumber("3.1478") )
    {
      // Bah its not a number!
    }
    Changing the return values to what you suggested would negate the logical use of the function.

  6. #6
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    Quote Originally Posted by jaro
    I've made a function that determines if character string is a number or not.
    Why not just learn how to use strtod? Consider also something like "+1.234E-05".
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  7. #7
    Registered User jaro's Avatar
    Join Date
    Mar 2006
    Location
    In my Parent House
    Posts
    34
    Quote Originally Posted by Thantos
    I think Salem was saying if you inputted "-." only it would register as a number.
    I just realized what Salem was really trying to convey after I post a reply.I was so comsumed in finding a fix in this error, that why I failed to understand it clearly.

    anyway, with your suggestion I have made some changes in the code.

    and here's the code
    Code:
    #include <string.h>
    #include <stdio.h>
    #include <ctype.h>
    
    int isNumber(char str[])
    {
    	int withDecimal =0,isNegative=0 ,i=0;
    	int len = strlen(str);
    
    	for (i=0; i<len; i++)
    	{
    		if (!isdigit(str[i])) // if1
    		{
    			if (str[i] == '.')
    			{
    				if(len!=1 && str[i+1] != '-')
    				{
    					if(withDecimal){
    						return 0;
    					}
    					withDecimal =1;
    				}else{
    					return 0;
    				}
    			}
    			else if (str[i] == '-')
    			{
    				if(len!=1){
    					if(str[i+1] == '.')
    					{
    						if(isdigit(str[i+2])){
    							if(isNegative){
    								return 0;
    							}
    
    							if(i==0){
    								isNegative = 1;
    							}else{
    								return 0;
    							}
    						}else{
    							return 0;
    						}
    					}
    				}else{
    					return 0;
    				}
    			}else{
    				return 0;
    			}
    		} //end if1
    	}// end for
    	return 1;
    }
    
    int main(){
    	
    	//for testing purpose only
    	char charNum[10][15] = {
    		"100.23" ,
    		"-200.456",
    		"200..",
    		"-..30",
    		"4.9.9.6",
    		"-.65",
    		"-0.54",
    		"-.",
    		".",
    		"-"
    	};
    
    	int cntr = 0;
    
    		for(cntr=0; cntr<10; cntr++){
    			printf("%s\t\t", charNum[cntr]);
    
    			if(isNumber(charNum[cntr])){
    				printf("is a number!\n");
    			}else{
    				printf("NOT a NUMBER!\n");
    			}
    		}
    
    }
    OUTPUT
    Code:
    100.23          is a number!
    -200.456        is a number!
    200..           NOT a NUMBER!
    -..30           NOT a NUMBER!
    4.9.9.6         NOT a NUMBER!
    -.65            is a number!
    -0.54           is a number!
    -.              NOT a NUMBER!
    .               NOT a NUMBER!
    -               NOT a NUMBER!
    regards,
    Jaro

  8. #8
    Registered User jaro's Avatar
    Join Date
    Mar 2006
    Location
    In my Parent House
    Posts
    34
    Quote Originally Posted by Dave_Sinkula
    Why not just learn how to use strtod? Consider also something like "+1.234E-05".
    just one quick question. can I use strtod in C?

    edit:
    just found out that I can use strtod in C. Well it does make works lot more easier
    Last edited by jaro; 05-17-2006 at 08:18 AM.

  9. #9
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,528
    Yes.

  10. #10
    Registered User jaro's Avatar
    Join Date
    Mar 2006
    Location
    In my Parent House
    Posts
    34
    Quote Originally Posted by Dave_Sinkula
    Why not just learn how to use strtod? Consider also something like "+1.234E-05".

    well strtod has made my number checking easy.and with less line of codes .

    I have added an extra function (checkNumber) in my code which basically do the same as the previous isNumber function .

    Code:
    #include <string.h>
    #include <stdio.h>
    #include <ctype.h>
    #include <stdlib.h>
    
    char errorNum[20]="";
    char tempVal[100]="";
    
    int isNumber(char str[])
    {
    	int withDecimal =0,isNegative=0 ,i=0;
    	int len = strlen(str);
    
    	for (i=0; i<len; i++)
    	{
    		if (!isdigit(str[i])) // if1
    		{
    			if (str[i] == '.')
    			{
    				if(len!=1 && str[i+1] != '-')
    				{
    					if(withDecimal){
    						return 0;
    					}
    					withDecimal =1;
    				}else{
    					return 0;
    				}
    			}
    			else if (str[i] == '-')
    			{
    				if(len!=1){
    					if(str[i+1] == '.')
    					{
    						if(isdigit(str[i+2])){
    							if(isNegative){
    								return 0;
    							}
    
    							if(i==0){
    								isNegative = 1;
    							}else{
    								return 0;
    							}
    						}else{
    							return 0;
    						}
    					}
    				}else{
    					return 0;
    				}
    			}else{
    				return 0;
    			}
    		} //end if1
    	}// end for
    	return 1;
    }
    
    
    int checkNumber(char str[]){
    
    	char *ok;
    	ok = str;
    	if(strlen(ok)==0){
    		return 1;
    	}else{
    		return 0;
    	}
    
    }
    
    
    int main(){
    	
    	//for testing purpose only
    	char charNum[10][15] = {
    		"100.23" ,
    		"-200.456",
    		"0.0",
    		"-..30",
    		".-",
    		"-.65",
    		"-0.54",
    		"0",
    		".",
    		"+1.234E-05"
    	};
    	
    	int cntr = 0;
    	
    
    		for(cntr=0; cntr<10; cntr++){
    			printf("%s\t\t", charNum[cntr]);
    
    			if(isNumber(charNum[cntr])){
    				printf("is a number!\n");
    			}else{
    				printf("NOT a NUMBER!\n");
    			}
    		}
    		
    		printf("\n=================================\n\n");
    
    		for(cntr=0; cntr<10; cntr++){
    
    			printf("%s\t\t", charNum[cntr]);
    			if(checkNumber(charNum[cntr])){
    				printf("is a number!\n");
    			}else{
    				printf("NOT a NUMBER!\n");
    			}
    		}
    
    }
    OUTPUT
    Code:
    100.23          is a number!
    -200.456        is a number!
    0.0             is a number!
    -..30           NOT a NUMBER!
    .-              NOT a NUMBER!
    -.65            is a number!
    -0.54           is a number!
    0               is a number!
    .               NOT a NUMBER!
    +1.234E-05      NOT a NUMBER!
    
    =================================
    
    100.23          is a number!
    -200.456        is a number!
    0.0             is a number!
    -..30           NOT a NUMBER!
    .-              NOT a NUMBER!
    -.65            is a number!
    -0.54           is a number!
    0               is a number!
    .               NOT a NUMBER!
    +1.234E-05      is a number!

    I haven't add any error checking in strtod() but as you can see, the function that uses strtod is clearly accurate.

    I'm not really familiar with the memory comsumption and portability by these function.
    So the question now is which of the two, isdigit() or strtod() is portable?
    and also between the two function checkNumber() and isNumber(), which is best to use, in terms of memory consumption.

    regards,
    jaro
    Last edited by jaro; 05-17-2006 at 09:21 AM. Reason: remove some variables in the checkNumber function

  11. #11
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,157
    Quote Originally Posted by wintellect
    Personally, I would have your function return 0 when the char is a digit and -1 on error

    ...but this is probablyon a personal thing
    Why would you do something like that? It's contrary to every other istype function (and C/C++ standards). Any idea what FALSE equates to?
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  12. #12
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    My version was like this.
    Code:
    int my_isNumber(const char str[])
    {
       char *end;
       double result = strtod(str, &end);
       return !isspace(*str) && end != str && *end == '\0';
    }
    I don't know whether you want to handle leading and trailing whitespace, however.

    Quote Originally Posted by jaro
    So the question now is which of the two, isdigit() or strtod() is portable?
    Both are standard C; that's about as portable as it gets.

    Quote Originally Posted by jaro
    and also between the two function checkNumber() and isNumber(), which is best to use, in terms of memory consumption.
    Code correctly first. If you have later proven it to be a troublesome bottleneck by profiling, then you worry about that. "Premature optimization is the root of all evil."
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. xor linked list
    By adramalech in forum C Programming
    Replies: 23
    Last Post: 10-14-2008, 10:13 AM
  2. Replies: 8
    Last Post: 04-25-2008, 02:45 PM
  3. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 10:03 PM
  4. Replies: 4
    Last Post: 03-03-2006, 01:11 AM
  5. Program using classes - keeps crashing
    By webren in forum C++ Programming
    Replies: 4
    Last Post: 09-16-2005, 03:58 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21