2017-04-23 37 views
0

我希望我的Java程序能夠與C程序通信。這只是一個簡單的例子,但我無法得到它的工作。 Java程序應該運行C程序並寫入其輸入流。 C程序應該看到這個並寫入標準輸出作爲響應。最後,Java程序應該從C程序的stdout中讀取這個響應並將其打印到屏幕上。使用標準輸入/輸出從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); 
    } 
} 

當我運行主,我得到下面的輸出:

$ java Main 
    done writing: hello 

然後只是閃爍的光標和文件「file.txt」沒有寫入,表明C程序沒有從標準輸入讀取「hello」。

這是一個簡單的例子,所以我想我錯過了一些簡單的東西或以某種方式以錯誤的方式來到這裏。

+1

首先:是C程序還是Java程序的問題?然後擺脫標籤和正在工作的代碼。 –

+0

我不知道。我在猜測Java程序,但我不確定。 – Yulek

+0

那麼,讓我們從這開始:鑑於Java程序調用C程序,C程序是否工作? –

回答

3

的問題是,你忘了換行字符\n(任何空格應該做的伎倆)添加到您正在從Java發送從而fscanf無限期地保持在等待的過程中"press 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); 
    } 
} 
+0

如果您使用'new String(buff,0,index)'來只轉換緩衝區的有效部分,則不需要數組副本。 (此外,剩餘元素包含顯示時不可見的字節值0,而不是包含Unicode的ASCII兼容代碼中的字符'0',它是0x30 aka 48.) –

+0

@ dave_thompson_085感謝您的輸入,我沒有想想'new String(buff,0,index)'的構造函數。關於尾隨零點,我認爲它們也是隱形的,但是它們出現在月食中,我認爲它們可能不出現在「真實」控制檯中,但沒有嘗試。我喜歡'new String(buff,0,index)'解決方案,並更新了我的答案以使用該方法。謝謝! – StaticBeagle

相關問題