Solved

How to discern 0 from NULL

Posted on 2002-07-06
7
204 Views
Last Modified: 2010-04-15
Hi,

I'm trying to write a simple program that takes 1 and only 1 commandline argument, and it must be an integer.  I couldn't find a function to help me, the only one I found, atoi, returned 3 if the argument was 3dddf (which is just dumb, IMHO).

I decided to write my own function, and it looks like so:

int CmdlineConverter(char * arg)
{
int i = 0;

  while (arg[i] != NULL)
  {
     if (isdigit((int) arg[i]) != 0)
       i++;
     else
       return NULL;

     return atoi(arg);
}

Then, in main, I call this function as CmdlineConverter(argv[1]) and check to make sure it is not == NULL before continuing.

If I am correct, my code above checks to make sure that the argument is all digits, in which case it returns the number, or it returns NULL.  It seems to work, except when the argument is zero.  The isdigit returns OK, so I know it recognizes zero as a digit.  It was my understanding that in C, zero and NULL are different values, but if I have return(0) instead of return atoi(arg), my IF (cmdlineconverter == NULL) code gets executed.  

What the heck am I doing wrong?






}
0
Comment
Question by:Sketchy
7 Comments
 
LVL 6

Expert Comment

by:zebada
ID: 7134260
NULL is usually a #define like this

#define NULL ((void *)0)

So in effect NULL is a pointer that points to memory location zero. Assigning a pointer to an integer usually just transfers the pointer value to the integer so in your case you cannot tell the difference between NULL and 0.
It is not considered goo practice to retrun a pointer when your function is declared as returning an integer.

Maybe you could try something like this instead:
int CmdlineConverter(int *result,char * arg)
{
  if not a valid number
    return -1;
  *result = atoi(arg);
    return 0;
}


0
 
LVL 11

Expert Comment

by:dimitry
ID: 7135640
In order to check if your string can be converted to integer without any problem you can use strtol() function.
You need to include <stdlib.h>

Function format:
 long strtol( char *nptr, char **endp, int base )

The strtol function converts 'nptr' to a long. strtol stops reading the string 'nptr' at the first character it cannot recognize as part of a number. This may be the terminating null character, or it may be the first numeric character greater than or equal to 'base'.

If you want it to check 'base' automatically, use 0.
'endp' will return pointer to character that stops scan.
If *endp != NULL then you have a problem in your string.





0
 
LVL 11

Accepted Solution

by:
griessh earned 50 total points
ID: 7136122
Sketchy

Your misunderstanding lies in the return value of your function. You are trying to return an integer if there is an integer available ann a Boolean FALSE if there is an error in the input. That doesn't work.
As alraedy explained, NULL is a #define, that means it can be everything, string, integer, char ... For your function NULL and '0' is the same, an integer!

To stay close to what you have:

int CmdlineCheck(char * arg)
{
int i = 0;

while (arg[i] != NULL)
{
    if (isdigit((int) arg[i]))
      i++;
    else
      return (0);

  return (1);
}

....

if (CmdlineCheck(arg)) result = atoi(arg)
else { printf "Illegal argument\n"; }
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 1

Expert Comment

by:yabelson
ID: 7140388
i dont see why you cant use a simple algorythm.
you can simply get the string,and check each character by its ascii value if its a number or not.
you can find the ascii table in any book or site.
once you establish that all your argument is made up of ints,you can simply use the (int*) to change it.
or you can do the same thing as before,but depleting the char by the difference between the numbers to their ascii value.
as for the ascii values:
0=48
1=49
2=50
...
9=57
0
 
LVL 3

Expert Comment

by:marcjb
ID: 7140549
Instead of checking for NULL, just check the number of arguments.  

if ( argc != 2 )
    return -1;  /* or print out an error message */

argv[0] will be the program name, and argv[1] will be the integer you asked for.

Also, dimitry gave what I think is the best answer for converting the data to a number and checking to see if the data is valid.  strtol (and strtoul) give you the information you need, and they are part of the Standard.

So...

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    long i;
    char **ptr;

    if ( argc != 2 ) {
        printf("Usage: %s integer\n", argv[0]);
     return -1;
    }

    /* Using strtol as dimitry suggested... */
    i = strtol(argv[1], ptr, 0);
    if ( **ptr != '\0' ) {
        printf("ERROR: argument '%s' contained non-numeric characters\n", argv[1]);
        return -2;
    }
    printf("You entered %ld\n", i);

    return 0;
}
0
 
LVL 1

Expert Comment

by:ris
ID: 7163229
Everyone has given very good answers already which are more to the point of your actual question...

Personally, I don't see what is wrong with allowing your program to be a little more robust and accept an argument like "3ddf" as the integer argument 3 without throwing an error and failing.  Though a warning would be nice.  I would do it something like this:

int main(int argc, char *argv[])
{
  if (argc<1)
  {
    printf("ERROR: not enough arguments");
    return 1;
  }
  else if (argc > 2)
  {
    printf("WARNING: too many arguments, all but the first will be ignored");
  }

  //convert the argument to an integer
  int nArgument = atoi(argv[1]);

  //now check to see that the number returned by atoi
  //can be turned back into the same string supplied on the command line
  if (strcmp(itoa(nArgument), argv[1]))
  {
    //there was some discrepancy in the format of the number string
    //but we have a value so it isn't critical and we can continue
    printf("WARNING: integer argument poorly formatted, assuming you meant to use %d", nArgument);
    //atoi("some non-number string") returns 0
    //so if the argument is zero, you could assume
    //that no number at all was supplied and fail utterly
    if (nArgument == 0)
    {
       printf("ERROR: actually, it seems that the argument was probably not a number at all, please try again");
       return 1;
  } //end if (argument didn't turn back into string)

  //continue with actual work...

  return 0; //indicates success
} //end main()
0
 
LVL 45

Expert Comment

by:Kdo
ID: 9480446
No comment has been added lately, so it's time to clean up this TA.

I will leave a recommendation in the Cleanup topic area that this question is:
Accept griessh's comment as answer

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Kent (Kdo)
EE Cleanup Volunteer
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now