首页 > 解决方案 > sscanf() 带有两个字符串参数

问题描述

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

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

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

标签: c++scanf

解决方案


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

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

其中N和分别是缓冲区M的最大宽度playername,例如:reasonkick

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

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

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

std::istringstream但是,在 C++ 中,使用andstd::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, ' '))
        {
            ...
        }
    }
}

推荐阅读