tags:

views:

242

answers:

5

My application is basically a shell which expects an input of type cmd [x], where cmd is constant and x is optional. So cmd 1 is legal as well as cmd by itself - then I assume a default parameter for x.

I am doing this:

char cmd[64];
scanf("%s", cmd);
int arg;
scanf("%d", &arg); // but this should be optional

How can I read the integer parameter, and set it to a default if none is currently available in the prompt? I do not want the prompt to wait for additional input if it was not given in the original command.

I tried several versions using fgetc() and getchar() and comparing them to EOF but to no avail. Each version I tried ends up waiting on that optional integer parameter.

+2  A: 

Simple answer, you can't. The C runtime takes input from the OS, but doesn't control it. To do something like this you will need to interact directly with the OS using platform specific APIs.

anon
Is that because the `stdin` never returns `EOF`? That is what I suspected...
Yuval A
No, stdin does return EOF but only after it encounters an end-of-file (e.g. the user typed Ctrl-D, or whatever), otherwise it just sits there waiting for the user to type something.
anon
That's what I meant... In the running context of an application it will never receive `EOF`, obviously, until terminated.
Yuval A
EOF is CTRL+D on Unix OS and CTRL+Z on Windows.
Let_Me_Be
Ctrl-D (on POSIX at least) doesn't terminate an app - it marks end of file on standard input.
anon
Offtopic: Heh! I just noticed you have 10 gold, 100 silver and 256 bronze badges... you have some nice round numbers!
Juliano
@Juliano Well, 1000 bronze would b rounder, I think.
anon
A: 

hey char *p; p=cmd;

for(;*p!='\0';++p) gets(p);

gcc
Even for the weekend, this is a bit clueless.
anon
+1  A: 

Are you reading line-by-line? Can't you just read the whole command until you reach a "\n" (newline)? If you get two tokens before the newline, it is a command and the argument; if you read only one, it is the command only and you set the second argument to the default.

Juliano
This is of course the correct solution - you really shouldn't be using scanf() for interactive input in the first place.
anon
+3  A: 

The easy way:

   char b[73]; //powers of 2 magic is evil.
    if(fgets(b,sizeof b,stdin) != NULL) {
      char cmd[59]; //59, no command will ever be > 58. Ever I say.
      int arg;
      if(sscanf(b,"%58s %d",cmd,&arg) == 2) {
         //handle cmd and arg
      } else if(sscanf(b,"%58s",cmd) == 1) {
         //handle cmd only
      } else {
       // :-/
      }
    }
leeeroy
Easy, but wrong - oops, you edited it.
anon
The second sscanf is unnecessary, if the first one returned 1, it had the same effect as the second sscanf.
Juliano
If the first one returned 1, how do you absolutly, 100% sure , in every case,compiler,platform, know it didn't parse 'arg' ok, but barfed on 'cmd' ? Though 1 or 2 sccanfs - It's still very suboptimal, as you'd really want to report errors to the user if he gave 2 arguments, but the 2. could not be parsed.
leeeroy
A: 

Here's a program that works (sorry my previous answer was made in haste).

int main(){
    char cmd[100], line[100];
    int man = 0;
    printf("OK: ");
    fgets(line, 100, stdin);
    int num = sscanf(line,"%s %d",cmd,&man);
    if (num==1)printf("one! %s %d\n", cmd, man);
    else if (num==2)printf("two! %s %d\n", cmd, man);
}

fgets reads the line (with bounds checking), and sscanf will assess whether one or two tokens were entered.

Jared Forsyth
dang, didn't refresh.
Jared Forsyth
You can (and should) delete your other answer.
anon
mk. I tried before and it said "do you want to vote for it to be deleted?" which didn't make sense...it's working now. thanks.
Jared Forsyth