简体   繁体   English

使用fscanf读取未知数量的命令

[英]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. 我正在从文件描述符(fp)中读取内容,以将命令从客户端发送到TCP服务器。 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. 我的问题是命令之一可以是“ move”,后跟两个整数。 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". 但是除非知道cmd是“ move”,否则我不能这样做。 Is there a way that I can get the command string, check for "move" and then get the integers? 有没有一种方法可以获取命令字符串,检查“ move”,然后获取整数?

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: 这是阅读move命令的可选参数的好地方:

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

Note: It is not safe to use %s , no matter how big a buffer you allocate. 注意:无论您分配多少缓冲区,使用%s都是不安全的。 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: while循环主体中:

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. 请注意,由于命令长于20个字符,缓冲区溢出将导致事实,因此您现在编写的代码并不安全。 You may wish to use, for example, "%20s" as your format string, to limit the length of the command. 您可能希望使用"%20s"作为格式字符串来限制命令的长度。

Alternatively, you can use fgets() to get a line of command, then parse it afterwards. 或者,您可以使用fgets()获取命令行,然后对其进行解析。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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