-1

I am trying to create a program that requires the user to enter a VALID integer as a command argument. I have tried literally everything I can think of and I can't get it to work. I have went through probably 10 different functions, scraping each one because I can tweak it to work.

This is what I have at the moment..

int checkdigit(char *argv) {
    int i = 0;
    for(i = 0; i <= strlen(argv); i++) {
        if (argv[i] >= 48 && argv[i] <= 57) {
            i++;
        } else {
            printf("Not valid");
            return 1;
        }
     }
     return 0;
}

This prints "Not valid" no matter what I give it.

user93938
  • 1
  • 1
  • You’re skipping every character after each valid digit. – dbush Apr 15 '18 at 21:33
  • 1
    There are two `i++` remove one. – Achal Apr 15 '18 at 21:35
  • 1
    Juding from the name of your parameter, you might have misunderstood the entire concept of using command line parameters. Have a look here https://stackoverflow.com/a/47536091/7733418 – Yunnosch Apr 15 '18 at 21:48
  • Don't use "magic numbers" like 48 and 57, that makes the code harder to read. Use the proper character constants instead: `if(argv[i] >= '0' && argv[i] <= '9')`. And if the condition in the for loop is `<= strlen(argv)`, then you are going to read the `'\0'`-terminating bytes. The correct condition should be `< strlen(argv)`.# – Pablo Apr 15 '18 at 22:34

3 Answers3

1

your condition is wrong while iterating in argv. It should be i<strlen(argv) instead of i<=strlen(argv). Also there are two i++ which will skip every valid digits.

here is the working one

int checkdigit(char *argv) {
        int i = 0;
        for(i = 0; i<strlen(argv); i++) {
                if (argv[i] >= 48 && argv[i] <= 57) {
                        continue;
                } else {
                        printf("Not valid");
                        return 1;
                }
        }
}

Also make sure you are calling checkdigit() correctly.

Achal
  • 11,821
  • 2
  • 15
  • 37
0

If you're passing an integer through argv, why wouldn't you use atoi? All you have to do is validate your parameters to verify you actually did pass enough arguments in.

The atoi function takes in a const char* argument and returns an int, which sounds exactly like what you're looking for.

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

int main(int argc, char *argv[])
{
    if (argc > 1) {
        for (int i = 1; i < argc; ++i) {
            printf("Digit: %d\n", atoi(argv[i]));
        }
    }

    return EXIT_SUCCESS;
}

Input:

./a.out 1 a 4 hello 72

Output:

Digit: 1
Digit: 0
Digit: 4
Digit: 0
Digit: 72

Update: Upon further research, strtol is the function you need. atoi does no error checking, and the C standard says nothing regarding what happens when atoi returns an error, so the function isn't considered safe, so while I initially thought the function was returning zero, it was actually returning an error.

If you have access to strtonum, that function is very reliable from what I've seen. I don't have access to it myself, since it seems to only be available on FreeBSD.

If you don't have access to that though, strtol is the way to go. It takes a const char* as input, so it does accept the right input for what you're looking for, as well as an end pointer and a base, and in addition it legitimately returns 0 on both successes and failure. It's at least going to be safer than using atoi.

0

After adding #include <ctype.h> at the top, I'd write your function this way:

  int checkdigit(char *argv) {
     int i = 0;
     for(i = 0; i<strlen(argv); i++) {
        if( !isdigit(argv[i]) ) {
           printf("Not valid");
           return 1;
        }
     }
     return 0;
  }

This would have the advantage of portability to non ASCII-based codepage environments, like IBM's System 39 or OS/400 which are EBCDIC based (in most native cases), and characters '0'-'9' have values 0xF0 through 0xF9.

JohnH
  • 2,713
  • 12
  • 21