简体   繁体   中英

Using fscanf to read an unknown number of commands

I'm reading from a file descriptor (fp) to get my commands from a client to my TCP server. The current way to get the command looks something like this

char cmd[21];
while ( fscanf( fp, "%s", cmd ) == 1 && strcmp( cmd, "quit" ) != 0 ) {
    //do work
}

My issue is that one of the commands can be "move" which is followed by two integers. I know that I can do something like

char cmd[21];
int row = 0;
int col = 0;
fscanf( fp, "%s%d%d", cmd, &row, &col );

but I can't do that unless I know that the cmd is "move". Is there a way that I can get the command string, check for "move" and then get the integers?

You can certainly do that. The trick is to wait until you know what kind of command you are processing.

At some point in your code your program would need to do something like this:

if (strcmp(cmd, "move") == 0) {
    ...
}

This is a good place to read your optional parameters for the move command:

fscanf( fp, "%d%d", &row, &col );

Note: It is not safe to use %s , no matter how big a buffer you allocate. You should always specify a limit for the number of characters your command buffer is prepared to accept, like this:

fscanf( fp, "%20s", cmd )
//            ^^

You can't easily do it exactly as you've outlined above, but you could do something like:

if (2 == fscanf(fp, "move %d %d", &row, &col))
   move(row, col);
// possibly similar checks for other commands here.
else if (fscanf(fp, "quit"))
    quit();

If the commands you need to support are all known when you write the code, this can be easier/simpler than reading the command, sorting out which command you have, then reading parameters appropriate for that command.

Conversely, if you might (for example) have some sort of plug-ins that add new commands to be supported, then you probably want to read the command, check it against some collection of installed commands (eg, a hash table) and use that to look up how to process that command (eg, at least find a number signifying the number of parameters to read for that command, and a function to which to pass those parameters for processing).

In the while loop body:

if(strcmp(cmd, "move") == 0) {
    fscanf(fp, "%d%d", &row, &col);
}

Note that your code as it is written now is not safe, due to the fact that a buffer overrun will occur if the command is longer than 20 characters. You may wish to use, for example, "%20s" as your format string, to limit the length of the command.

Alternatively, you can use fgets() to get a line of command, then parse it afterwards.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM