LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-21-2023, 04:16 PM   #1
jmgibson1981
Member
 
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 952

Rep: Reputation: 325Reputation: 325Reputation: 325Reputation: 325
Tried to solve a problem. Probably a better way. Asking for tips to simplify.


My first attempt at creating something. I have no doubt there is a better way to do this. be gentle please. this is to verify that floats or integers are the only acceptable input for my calculator i've been working on.

Code:
int valid_numbers(char numtest[24])
{
    // declare and set variables
    int total_chars = strlen(numtest);
    int total_char_test;
    int difftest;
    for (int i = 0; i < total_chars; i++)
    {
        if (isdigit(numtest[i]))
        {
            // if number is digit then increment test variable
            total_char_test++;
        }
    }

    // set variable difference total & test
    difftest = total_chars - total_char_test;
    if (difftest == 1 && strchr(numtest, '.') != NULL)
    {
        return 0;
    }
    if (difftest > 1)
    {
        return 1;
    }
    return 0;
}
*edit* found it didn't work.updated code above to working config.

Last edited by jmgibson1981; 01-21-2023 at 10:19 PM.
 
Old 01-22-2023, 11:03 AM   #2
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,682

Rep: Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008
You didn't initialize total_char_test to 0, it might work by accident right now, but depending on some unrelated things might fail to work later. I think the compiler should be warning you about this if you set the right options.

For readability, I would suggest naming that variable total_digits, or something like that instead. Also, the 24 in char numtest[24] is not doing anything so I suggest to remove it (maybe you want to add a test against total_chars that it's 24 or less?)

Do you consider "123." or ".123" as valid integers or floats? (That's not rhetorical, any choice you make here is fine, as long as you've thought about it)
 
1 members found this post helpful.
Old 01-22-2023, 11:06 AM   #3
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 19,594

Rep: Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629
you can try to count non-digit chars, and stop (return 1) if more than one found or is not dot. That would be probably a bit better.
You can also check the minus sign (if you wish). And probably you want to handle longer numbers too. And check the end-of-string.
Otherwise it looks ok.
 
1 members found this post helpful.
Old 01-22-2023, 12:47 PM   #4
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 19,594

Rep: Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629
regarding validity, a "regular" decimal number must not start with 0 (zero) if it is >1 and must not end with 0 if there is a decimal point somewhere. But these are not that important, you can simply cut them (leading and trailing zeros) if you wish.
 
Old 01-22-2023, 02:15 PM   #5
Keith Hedger
Senior Member
 
Registered: Jun 2010
Location: Wiltshire, UK
Distribution: Linux From Scratch, Slackware64, Partedmagic
Posts: 3,056

Rep: Reputation: 831Reputation: 831Reputation: 831Reputation: 831Reputation: 831Reputation: 831Reputation: 831
Quote:
Originally Posted by pan64 View Post
regarding validity, a "regular" decimal number must not start with 0 (zero) if it is >1 and must not end with 0 if there is a decimal point somewhere. But these are not that important, you can simply cut them (leading and trailing zeros) if you wish.
?
100 and 100.0 both valid decimal numbers both end in 0 or am I missing somthing?
 
Old 01-22-2023, 03:29 PM   #6
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,760
Blog Entries: 13

Rep: Reputation: 4803Reputation: 4803Reputation: 4803Reputation: 4803Reputation: 4803Reputation: 4803Reputation: 4803Reputation: 4803Reputation: 4803Reputation: 4803Reputation: 4803
You could approach it with ever increasing checks.

Plus or minus should only be the first character.
There only should ever be one decimal point.
The rest can be digits, but there are some rules to consider which you can decide as to what is allowable.
 
Old 01-22-2023, 10:13 PM   #7
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,101
Blog Entries: 4

Rep: Reputation: 3662Reputation: 3662Reputation: 3662Reputation: 3662Reputation: 3662Reputation: 3662Reputation: 3662Reputation: 3662Reputation: 3662Reputation: 3662Reputation: 3662
Actually, if you are seriously interested in knowing more about "how cheap calculators actually do it," you may wish to someday explore the concept of a FSM = Finite-State Machine.

Such as this web-site which actually discusses the specific implementation of "a calculator." https://mitadmissions.org/blogs/entr...th-fsm-logic1/

"Finite-State Machines" are actually a very-important but maybe counter-intuitive class of algorithms which are actually very relevant to problems of this sort. In summary, the "machine" processes its input "one input at a time," while maintaining an internal "state" to dictate exactly how it should process "any possible input" at "this particular time (in this particular 'state' ...)
 
Old 01-22-2023, 11:12 PM   #8
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,682

Rep: Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008Reputation: 2008
Quote:
Originally Posted by sundialsvcs View Post
you may wish to someday explore the concept of a FSM = Finite-State Machine.

Such as this web-site which actually discusses the specific implementation of "a calculator." https://mitadmissions.org/blogs/entr...th-fsm-logic1/
It looks like they are using a finite state machine to handle operator precedence. It's certainly possible to do this when there are only two* levels of precedence (plus/minus vs multiply/divide), but in my opinion it's not a good approach because it leads to an overly complex set of states, and you should not follow this example.

* or any finite number of levels n if you're willing to handle 2ⁿ states, but you can't handle arbitrarily nested parentheses with a finite state machine.
 
Old 01-23-2023, 02:03 AM   #9
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 19,594

Rep: Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629Reputation: 6629
Quote:
Originally Posted by Keith Hedger View Post
?
100 and 100.0 both valid decimal numbers both end in 0 or am I missing somthing?
Yes, 001000.34 is not really acceptable, 213.343000 again. That's what I wanted to explain. Next time I will try to explain better, that was not that perfect.
 
Old 01-24-2023, 03:13 PM   #10
GazL
LQ Veteran
 
Registered: May 2008
Distribution: CRUX 3.7
Posts: 6,592

Rep: Reputation: 4708Reputation: 4708Reputation: 4708Reputation: 4708Reputation: 4708Reputation: 4708Reputation: 4708Reputation: 4708Reputation: 4708Reputation: 4708Reputation: 4708
Another approach would be to use strtol() and then call strtod() when there's a fractional component (i.e. when *endptr == '.' ).

Something like this perhaps:
Code:
#include <stdio.h>
#include <stdlib.h>

void *validate_number_str( char *nstr, long *return_long, double *return_double)
{
	char *endptr;

	if ( nstr == NULL || return_long == NULL )
		return NULL;

	*return_long =  strtol(nstr, &endptr, 10);
	if ( endptr == nstr )
		return NULL;

	if ( return_double  &&  *endptr == '.' )
	{
		*return_double = strtod(nstr, &endptr);
		if ( *endptr == '\0' )
			return return_double;
	} else if ( *endptr == '\0' )
		return return_long;

	return NULL;
}

int main(int argc, char *argv[])
{

	double my_double;
	long my_long;

	if (argc < 2 )
		return 1;

	void *ptr = validate_number_str(argv[1], &my_long, &my_double );

	if (ptr == &my_long )
		printf("valid long %ld\n", my_long);
	else if ( ptr == &my_double )
		printf("valid double %f\n", my_double);
	else
		printf("Invalid\n");

	return 0;
}
I'll leave stripping trailing whitespace and any further robustness checks as an exercise for the reader.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Tried to patch my kernel and probably failed : what do ? User-N@me Debian 7 06-02-2011 10:32 PM
how to solve solve broken shell problem prasanth.george Red Hat 1 01-21-2011 10:48 AM
New graphics card issues - probably simple to solve ben909 Ubuntu 5 05-13-2009 01:47 AM
network connectivity...probably easy to solve.. nooodles Linux - Networking 3 09-29-2005 10:05 PM
"Simplify! Simplify!" BillRice Linux - General 6 03-15-2002 02:35 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:59 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration