views:

806

answers:

5

I'm writing a small application in C that takes two parameters. One is a filename, the other a number, and they may be specified in random order.

./main filename 12345

and

./main 12345 filename

should both work.

How can I easily determine which is which when I know the filename starts with a character?

A: 
if ('0' <= argv[1][0] && argv[1][0] <= '9')
{
    /* it starts with a number */
}
rlbond
+9  A: 

You can use the isalpha and isdigit functions (defined in ctype.h) on the first character of argv[1] or argv[2].

Keith Randall
The main problem with every solution like this comes if you have a filename which is a legal number. So you would have to check the whole string if it only consists of a number and then also if it is no existing file.
frenetisch applaudierend
@frenetisch, that would not be a problem with this answer, but with the question itself. And it's not even a problem with the question since the OP states that all the filenames start with a character.
paxdiablo
+4  A: 

You can use the ctype functions.

if (isalpha(*argv[1]))
    // argv[1] starts with a letter
else if (isdigit(*argv[1])
    // argv[1] starts with a number
R Samuel Klatchko
And don't forget to handle the `else` case as well... `./main /path/to/file 666`. Just using isdigit(), and presuming filename otherwise is probably better.
ndim
You should cast `*argv[1]` to `unsigned char`, since it is of type `char`, and `isalpha` and `isdigit` specify that their argument must be in the range of `unsigned char` or `EOF`.
caf
+2  A: 

Use isdigit.

isdigit((unsigned char)argv[1][0])

Make sure you check argc first.

avakar
+1 for the required cast to `unsigned char`
pmg
A: 

You can also use the sscanf() function, which returns the number of successfully scanned items:

int number;
char *string;

if (sscanf (argv[1], " %d ", &number) == 1) { /*12345 filename */
  string = malloc ((strlen (argv[2]) + 1) * sizeof (char));
  sscanf (argv[2], " %s ", string);
}
else { /* filename 12345 */
  sscanf (argv[2], " %d ", &number);
  string = malloc ((strlen (argv[1]) + 1) * sizeof (char));
  sscanf (argv[1], " %s ", string);
}

If argv[1] is a string starting with a character the first clause will return "zero".

Leonardo de Oliveira Martins
There's no need to copy strings in this case, you can just assign `string` directly to `argv[1] or `argv[2]` as appropriate.
Adam Rosenfield
You are right, Adam, they're within same scope. Thanks for pointing that out.
Leonardo de Oliveira Martins