使用 Java 中的 stdin/out 与 C 程序通信 [英] Communicate with C program using stdin/out from Java

查看:23
本文介绍了使用 Java 中的 stdin/out 与 C 程序通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want my Java program to communicate with a C program. This is just a simple example but I can't get it working. The Java program is supposed to run the C program and write to its input stream. The C program should see this and write to stdout in response. Finally, the Java program should read this response from the C program's stdout and print it to the screen.

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

Running the C program from command line I get the desired behaviour. However, when ran from the Java program, it just "hangs" and doesn't do anything. The Java program seems to have written its message to C program's stdin, but this message isn't seen in the C program.

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

I set the C program to write the message it reads to file just to check that it does read the message, and it doesn't do that.

这是 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 程序:

And here's the Java program:

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 时,我得到以下输出:

When I run Main, I get the following output:

$ java Main
  done writing: hello

然后只是一个闪烁的光标和文件file.txt"没有写入,表明C程序没有从stdin读取hello".

And then just a blinking cursor and file "file.txt" is not written, indicating that the C program didn't read "hello" from stdin.

这是一个简单的例子,所以我想我错过了一些简单的东西,或者以某种方式错误地解决了这个问题.

This is a simple example so I guess I'm missing something simple or coming at this the wrong way somehow.

推荐答案

问题是你忘记在你从 Java 发送的字符串中添加换行符 \n 因此 fscanf 无限期地等待进程按回车".我对代码进行了一些修改,这些更改记录在注释中.

The problem is that you forgot to add the new line character \n to the string that you are sending from Java thus fscanf keeps waiting indefinitely for the process to "press enter". I've made some modifications to the code and the changes are documented in comments.

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);
    }
}

这篇关于使用 Java 中的 stdin/out 与 C 程序通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆