gpt4 book ai didi

java - 使用 ProcessBuilder 通过交互式 IO 运行 C 程序

转载 作者:行者123 更新时间:2023-12-02 02:08:27 28 4
gpt4 key购买 nike

我正在使用 java 为 C/C++ 开发一种 IDE 类型的软件(虽然有很多可用的,但我想要我自己的)可以编译和执行C或C++程序。所以我尝试了一个简单的程序来编译和执行java中的C程序,使用 ProcessProcessBuilder.

这是我的简单 java 程序,它编译并执行 C 程序:

public class RunProgram {

public static void main(String[] args) throws Exception {
new ProcessBuilder("gcc", "-o", "first", "first.c").start().waitFor(); //To Compile the source file using gcc and wait for compilation


/*
Although I've to handle error-stream but
for now, my assumption is that there is no error
in program.
*/


ProcessBuilder run = new ProcessBuilder("./first");

execute.redirectErrorStream(true);

Process runProcess = run.start();

StreamReader sr = new StreamReader(runProcess.getInputStream());

new Thread(sr).start(); //A new thread to handle output of program .

//rest of coding to provide input using OutputStream of 'runProcess' and to close the stream.

}
}

class StreamReader implements Runnable {

private InputStream reader;

public StreamReader(InputStream inStream) {
reader = inStream;

}

@Override
public void run() {

byte[] buf = new byte[1024];

int size = 0;
try {

while ((size = reader.read(buf)) != -1) {

System.out.println(new String(buf));
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

这是我的first.c程序。

#include<stdio.h>

int main() {
int a;
int k;

printf("input a: ");

scanf("%d", &a);
for(k = 0; k < a; k++)
printf("k = %d\n", k);
return 0;
}

我想创建交互式IO控制台就像大多数 IDE 或命令终端一样(Linux 操作系统中的终端和 Windows 操作系统中的命令提示符)。对于上面的例子:首先,它应该打印 “Input a: “然后等待提供输入,然后等待程序的其余部分。但是它不会像我想象的那样工作,因为它不会打印 printf 的结果声明出现在scanf之前直到我可能使用 OutputStream 提供输入.

我用谷歌搜索了我的问题并访问了许多链接,但没有得到解决方案。与此同时,我发现this建议附加 fflush 的链接每次printf之后声明或使用setbufsetvbuf方法(来自其他一些子链接)清除缓冲区。但是一个新人(即将学习 C 语言)可能不知道 fflush或者这些功能,他/她永远不会使用它,因为它不需要在其他 IDE 中,甚至不需要在终端上。如何解决这个问题并为我的 IDE 构建集成控制台

这是我想要的一瞥:

animation of Interactive IO

最佳答案

根据上面的评论,我认为添加一点关于 I/O 流缓冲如何工作的解释在这里是有意义的。

当调用printf(3)等时,幕后发生的事情是数据被写入缓冲区,直到缓冲区填满或发生某些触发。然后缓冲区的内容从缓冲区复制到实际输出设备/另一个输出缓冲区...触发器通常遇到行尾(Linux/Unix 下的 \n)。因此,这种缓冲的粗略版本是:

struct buffered_file_t {

char* buffer;
size_t capacity;
size_t current_char;
FILE* file;

};

void flush_buffered(struct buffered_file_t* file) {

assert(0 != file);
assert(0 != file->buffer);

fwrite(file->buffer, file->current_char, 1, file->file);
file->current_char = 0;

}


void print(struct buffered_file_t* file, const char* str) {

assert(0 != file);
assert(0 != file->buffer);
assert(0 != str);

for(size_t i = 0; 0 != str[i]; ++i) {

if(file->current_char >= file->capacity - 1) flush_buffered(file);
file->buffer[file->current_char++] = str[i];
if('\n' == str[i]) flush_buffered(file);

}

}

现在,如果您像

那样调用 print
const size_t BUFSIZE = 100;

struct buffered_file_t stdout_buffered = {
.buffer = calloc(1, BUFSIZE),
.capacity = BUFSIZE,
.current_char = 0,
.file= stdout,
};

print(&stdout_buffered, "Naglfar\n");
print(&stdout_buffered, "Surthur");

您永远不会在stdout 上看到Surthur 出现。为了将其从缓冲区写入 stdout,您必须

  • 显式调用flush_buffered
  • 通过减小缓冲区大小来禁用缓冲(上例中的buffered_file.capacity = 1)

在您的情况下,您无法显式调用 fflush(3) (这就是您所说的要求)。因此剩下的唯一方法就是禁用缓冲。

恕我直言,如何做到这一点取决于操作系统。对于 Linux,请查看 Coreutils 包中的 stdbuf(1),了解如何禁用某些外部进程流的缓冲。

关于java - 使用 ProcessBuilder 通过交互式 IO 运行 C 程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50404978/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com