带有两个字符串参数的 sscanf()

sscanf() with two string parameters

我想在 C++ 中创建命令 /kick playername reason,所以我试了一下:

if (IPlayer.IsOnline() && IPlayer.GetAdmin() >= 3
    && sscanf(command, "/kick %[a-z | A-Z | 0-9/<>|.,~*;`:!'^+%&/()=?_-£#${[]}€] %[a-z | A-Z | 0-9/<>|.,~*;`:!'^+%&/()=?_-£#${[]}€]",
        &playername, &reasonkick) == 2)

但是当我在游戏中使用命令时没有任何反应。语法错误吗?

sscanf() 不支持正则表达式。您使用 %[] 占位符的方式确实是错误的语法。试试这个:

if (IPlayer.IsOnline() &&
    (IPlayer.GetAdmin() >= 3) &&
    (sscanf(command, "/kick %N[^ ] %Ms", playername, reasonkick) == 2))
{
    ...
}

其中NM分别是playernamereasonkick缓冲区的最大宽度,例如:

char playername[51] = {};
char reasonkick[129] = {};

if (IPlayer.IsOnline() &&
    (IPlayer.GetAdmin() >= 3) &&
    (sscanf(command, "/kick %50[^ ] %128s", playername, reasonkick) == 2))
{
    ...
}

%N[^ ] 将扫描输入字符串,直到遇到 space 个字符或扫描到 N 个字符。无需指定可能遇到的所有单个字符。 %Ms 将扫描输入字符串的其余部分,直到到达字符串末尾或扫描到 M 个字符。如果需要,您可以使用 %M[^ ] 作为该参数。

但是,在 C++ 中,使用 std::istringstreamstd::getline() 代替 sscanf() 会更好地处理这个问题,例如:

if (IPlayer.IsOnline() && (IPlayer.GetAdmin() >= 3))
{
    std::istringstream iss(command);
    std::string cmd;
    if (std::getline(iss, cmd, ' ') && (cmd == "/kick"))
    {
        std::string playername, reasonkick;
        if (std::getline(iss >> std::ws, playername, ' ') &&
            std::getline(iss >> std::ws, reasonkick, ' '))
        {
            ...
        }
    }
}