当前位置: 首页 > 知识库问答 >
问题:

使用Java的stdin/out与C程序通信

漆雕嘉茂
2023-03-14

我希望我的Java程序与一个C程序通信。这只是一个简单的例子,但我无法让它工作。Java程序应该运行C程序并写入其输入流。C程序应该看到这一点并写入标准输出作为响应。最后,Java程序应该从C程序的标准输出中读取这个响应并将其打印到屏幕上。

从命令行运行 C 程序,我得到了所需的行为。但是,当从 Java 程序运行时,它只是“挂起”并且不执行任何操作。Java 程序似乎已经将其消息写入了 C 程序的 stdin,但在 C 程序中看不到此消息。

我将C程序设置为将它读取的消息写入文件,只是为了检查它是否读取了消息,但它没有这样做。

以下是C程序:

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

void hello();
void wrong();

int main() {
    char buff[256];

    /* 1. read stdin */
    fscanf(stdin, "%s", buff);

    /* side effect - if message was received it should be 
        printed to file */
    FILE *fp = fopen("file.txt", "w");
    fprintf(fp, "%s", buff);
    fclose(fp);

    /* 2. depending on message, write something to stdout */
    if(strcmp(buff, "hello") == 0) {
        hello();
    } else {
        wrong();
    }
}

void hello() {
    printf("Hello World!");
}

void wrong() {
    printf("WRONG!");
}

下面是Java程序:

import java.io.*;

public class Main {
    public static void main(String[] args) {
        try {
            // 1. run C program
            Process proc = Runtime.getRuntime().exec("./hello");
            InputStream in = proc.getInputStream();
            OutputStream out = proc.getOutputStream();
            // 2. write 'hello' to 'hello' program
            writeToProc(out, "hello");
            // 3. read response
            readFromProc(in);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    // write message to process
    public static void writeToProc(OutputStream out, String msg) throws IOException {
        byte[] buff = msg.getBytes();
        out.write(buff);
        out.flush();
        System.out.println("done writing: " + new String(buff));
    }

    // read stdin of process
    public static void readFromProc(InputStream in) throws IOException {
        byte[] buff = new byte[256];
        int read = in.read();
        for(int i=0; read != -1; i++) {
            read = in.read();
            buff[i] = (byte) read;
        }
        String str = new String(buff);
        System.out.println("proc says: " + str);
    }
}

当我运行 Main 时,我得到以下输出:

$ java Main
  done writing: hello

然后只是一个闪烁的光标和文件“file.txt”没有被写入,说明C程序没有从stdin中读取“hello”。

这是一个简单的例子,所以我想我错过了一些简单的东西,或者以某种方式走错了方向。

共有1个答案

濮阳国兴
2023-03-14

问题是您忘记了在从Java发送的字符串中添加新行字符< code>\n,因此< code>fscanf会无限期地等待进程< code >“按enter”。我对代码做了一些修改,修改记录在注释中。

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Main {
    public static void main(String[] args) {
        try {
            // 1. run C program
            Process proc = Runtime.getRuntime().exec("./hello");
            InputStream in = proc.getInputStream();
            OutputStream out = proc.getOutputStream();
            // 2. write 'hello' to 'hello' program
            // <change>
            // don't forget to add the new line here or in the 
            // writeToProc method
            writeToProc(out, "hello\n");
            // 3. read response
            readFromProc(in);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    // write message to process
    public static void writeToProc(OutputStream out, String msg) throws IOException {
        // <change>
        // Using UTF-8 encoding since all chars in C are byte sized
        byte[] buff = msg.getBytes("UTF-8");
        out.write(buff);
        out.flush();
        System.out.println("done writing: " + new String(buff));
    }

    // read stdin of process
    public static void readFromProc(InputStream in) throws IOException {
        byte[] buff = new byte[256];
        int read = in.read();
        int index = 0;
        while(read != -1) {
            buff[index] = (byte) read;
            read = in.read();
            ++index;
        }
        String str = new String(buff, 0, index);
        System.out.println("proc says: " + str);
    }
}
 类似资料:
  • 我试图与一个进程通信(该进程本身会写入stdin和stdout,以便在终端中与用户交互),并在C中读取它的stdin和写入它的stdout。 因此,我尝试以编程方式替换shell用户。一个methapohrical示例:假设出于某种原因我想在C中使用VIM。然后我还需要编写命令(stdout)并从编辑器(stdin)中读取内容。 起初我认为这可能是一项微不足道的任务,但似乎没有标准的方法<代码>i

  • 问题内容: 我有以下程序: 我面临的问题是,一旦在STDIN上检测到输入,消息“ User input- stdin”就继续打印…为什么在循环检查哪一个描述符已输入的同时,它一次又不打印一次? 谢谢。 问题答案: 该功能仅在有可用输入时告诉您。如果您实际上并没有消耗它,那么select将继续直接下降。

  • 问题内容: 我正在尝试从Java程序运行外部程序,但遇到了麻烦。基本上我想做的是这样的: 但是,我发现这是行不通的-Java清单需要使用带有输入和输出流以及其他我没有经验的东西。 我看了互联网上的许多示例(其中许多来自SO),并且似乎没有一种简单的标准方法来完成此操作,对于不完全了解正在发生的事情的人来说,可能非常令人沮丧。 我也很难在其他人的代码示例上构建自己的代码,因为通常看来,大多数其他人1

  • 问题内容: 在Windows上,我们有一个C ++应用程序来启动Java进程。这两个应用程序需要彼此通信(通过xml片段)。 您将选择哪种进程间通信方法,为什么? 我们桌上的方法是:共享文件,管道和套接字(尽管我认为这有一些安全问题)。我愿意接受其他方法。 问题答案: 我不确定为什么您认为基于套接字的通信会带来安全隐患(使用SSL)。假设您具有明确定义的通信协议,这通常是一种非常好的方法,因为它与

  • 如何使用fifo重定向进程的stdin? 使用system d,我正在启动一个不经常需要通过stdin发送命令的服务。为了克服这个问题,我尝试了以下方法: 我可以使用以下命令运行命令。 我遇到的问题是,这似乎只适用于一个命令。在运行这个命令一次之后,所有其他写入fifo的调用似乎都被挂起,服务器再也不会处理其他任何事情。 如何使用fifo将输入重定向到守护进程的stdin?

  • 问题内容: 我得去查档案主.py以及儿童.py. 我正试图把一个字符串发送到主.py. 这是我不完整的代码: child.py I have no idea how to do this. I am running windows 10 with python 3.5.1 -谢谢 编辑:当我将参数发送回主.py,我无法重新打开 程序。操作系统重新打开在我的情况下没有用的程序。 这些程序是我尝试做的