Communicate with C program using stdin/out from Java

為{幸葍}努か 提交于 2021-02-05 11:34:12

问题


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.

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.

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.

Here is the C program:

#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!");
}

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

When I run Main, I get the following output:

$ java Main
  done writing: 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.


回答1:


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


来源:https://stackoverflow.com/questions/43577359/communicate-with-c-program-using-stdin-out-from-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!