使用C ++与Stockfish shell连接

时间:2015-08-30 21:39:40

标签: c++ shell

我正在尝试编写一个通过命令行与Stockfish国际象棋引擎连接的程序。我已经研究过使用管道和重定向cin / cout,但问题是Stockfish运行自己的shell而不是只输出单行输出,例如:

~$ stockfish 
Stockfish 261014 64 by Tord Romstad, Marco Costalba and Joona Kiiski
> go movetime 5000
[output]
...
> quit
~$

我尝试了以下代码(来自here)来读取执行命令并将其读回,但是当我尝试运行Stockfish并打印输出时它永远不会完成:

#include <string>
#include <iostream>
#include <stdio.h>

std::string exec(char* cmd) {
    FILE* pipe = popen(cmd, "r");
    if (!pipe) return "ERROR";
    char buffer[128];
    std::string result = "";
    while(!feof(pipe)) {
        if(fgets(buffer, 128, pipe) != NULL)
            result += buffer;
    }
    pclose(pipe);
    return result;
}

int main(void)
{
    std::cout << exec("ls") << std::endl; // this works fine
    std::cout << exec("stockfish") << std::endl; // this never ends

    return 0;
}

我的问题是,为什么没有这项工作,我怎样才能编写一个可以从Stockfish shell发送和接收文本的程序?

1 个答案:

答案 0 :(得分:0)

你的while循环只有在检测到管道上的EOF时才会完成,直到popen'd命令终止才会发生。等待输入的事实基本上是不可检测的。

由于popen只重定向了stdout,因此popen'd stockfish与你的程序共享stdin。当你启动鳕鱼时,它会尝试读取输入。如果你没有打字,什么都不会发生。

所以你应该尝试向你发送你想要它执行的命令,以“退出”命令结束。

Popen只允许您发送接收数据,具体取决于模式操作数。你永远不能做到这两点。你可以使用通常的forkexec技术,或者你可以像stockfish < sfcmds.txt那样使用某些技巧。