【修改】 C语言判分后输出中文变乱码
This commit is contained in:
@@ -120,18 +120,22 @@ public class JudgementCUtils
|
||||
}
|
||||
public static String run_codes(String pathC, String code, String input, String standard, String text) {
|
||||
try {
|
||||
boolean hasInput = code.contains("scanf") || code.contains("fgets") || code.contains("getchar");
|
||||
boolean hasInput = code != null && (code.contains("scanf") || code.contains("fgets") || code.contains("getchar"));
|
||||
|
||||
File workDir = new File(pathC);
|
||||
if (!workDir.exists()) workDir.mkdirs();
|
||||
|
||||
boolean isWindows = System.getProperty("os.name").toLowerCase().contains("win");
|
||||
java.nio.charset.Charset charset = pickCharset(text, isWindows);
|
||||
|
||||
String programC = new File(workDir, "program.c").getAbsolutePath();
|
||||
String programOut = new File(workDir, isWindows ? "program.exe" : "program.out").getAbsolutePath();
|
||||
|
||||
// 写入 C 源码
|
||||
try (FileWriter writer = new FileWriter(programC)) {
|
||||
writer.write(code);
|
||||
// 写入 C 源码(按指定字符集)
|
||||
try (java.io.OutputStream os = new java.io.FileOutputStream(programC);
|
||||
java.io.OutputStreamWriter writer = new java.io.OutputStreamWriter(os, charset)) {
|
||||
writer.write(code == null ? "" : code);
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
// jar 所在目录
|
||||
@@ -149,21 +153,15 @@ public class JudgementCUtils
|
||||
}
|
||||
|
||||
// 编译命令
|
||||
ProcessBuilder compileBuilder;
|
||||
if (stdFlag == null) {
|
||||
compileBuilder = new ProcessBuilder(tccExe.getAbsolutePath(), programC, "-o", programOut);
|
||||
} else {
|
||||
compileBuilder = new ProcessBuilder(tccExe.getAbsolutePath(), stdFlag, programC, "-o", programOut);
|
||||
}
|
||||
ProcessBuilder compileBuilder = (stdFlag == null)
|
||||
? new ProcessBuilder(tccExe.getAbsolutePath(), programC, "-o", programOut)
|
||||
: new ProcessBuilder(tccExe.getAbsolutePath(), stdFlag, programC, "-o", programOut);
|
||||
|
||||
compileBuilder.directory(workDir);
|
||||
compileBuilder.redirectErrorStream(true);
|
||||
|
||||
Process compileProcess = compileBuilder.start();
|
||||
StringBuilder compileOutput = new StringBuilder();
|
||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(compileProcess.getInputStream(), StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) compileOutput.append(line).append("\n");
|
||||
}
|
||||
String compileOutput = readAll(compileProcess.getInputStream(), charset);
|
||||
int compileResult = compileProcess.waitFor();
|
||||
if (compileResult != 0 || !new File(programOut).exists()) {
|
||||
return "❌ 编译失败,输出:\n" + compileOutput;
|
||||
@@ -176,29 +174,25 @@ public class JudgementCUtils
|
||||
Process runProcess = runBuilder.start();
|
||||
|
||||
if (hasInput && input != null) {
|
||||
try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(runProcess.getOutputStream()))) {
|
||||
try (java.io.OutputStream os = runProcess.getOutputStream();
|
||||
java.io.OutputStreamWriter osw = new java.io.OutputStreamWriter(os, charset);
|
||||
java.io.BufferedWriter bw = new java.io.BufferedWriter(osw)) {
|
||||
bw.write(input);
|
||||
bw.newLine();
|
||||
bw.flush();
|
||||
}
|
||||
} else {
|
||||
// 关闭输入流,避免某些程序等待 STDIN
|
||||
try { runProcess.getOutputStream().close(); } catch (Exception ignore) {}
|
||||
}
|
||||
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
Future<String> future = executor.submit(() -> {
|
||||
StringBuilder output = new StringBuilder();
|
||||
// 运行过程读取输出
|
||||
try (BufferedReader br = new BufferedReader(
|
||||
new InputStreamReader(runProcess.getInputStream(), StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) output.append(line).append("\n");
|
||||
}
|
||||
return output.toString();
|
||||
});
|
||||
java.util.concurrent.ExecutorService executor = java.util.concurrent.Executors.newSingleThreadExecutor();
|
||||
java.util.concurrent.Future<String> future = executor.submit(() -> readAll(runProcess.getInputStream(), charset));
|
||||
|
||||
String output;
|
||||
try {
|
||||
output = future.get(5, TimeUnit.SECONDS);
|
||||
} catch (TimeoutException e) {
|
||||
output = future.get(5, java.util.concurrent.TimeUnit.SECONDS);
|
||||
} catch (java.util.concurrent.TimeoutException e) {
|
||||
runProcess.destroyForcibly();
|
||||
future.cancel(true);
|
||||
output = "⏰ 程序运行超时(超过 5 秒)";
|
||||
@@ -213,6 +207,31 @@ public class JudgementCUtils
|
||||
return "运行 C 代码时出错:" + ex.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private static java.nio.charset.Charset pickCharset(String text, boolean isWindows) {
|
||||
if (text != null && !text.isBlank()) {
|
||||
try {
|
||||
return java.nio.charset.Charset.forName(text.trim());
|
||||
} catch (Exception ignore) {
|
||||
// ignore and fallback
|
||||
}
|
||||
}
|
||||
// 常见场景:Windows 中文环境默认 GBK;其他系统默认 UTF-8
|
||||
return isWindows ? java.nio.charset.Charset.forName("GBK") : java.nio.charset.StandardCharsets.UTF_8;
|
||||
}
|
||||
|
||||
private static String readAll(java.io.InputStream is, java.nio.charset.Charset cs) throws java.io.IOException {
|
||||
try (java.io.InputStream in = is;
|
||||
java.io.InputStreamReader isr = new java.io.InputStreamReader(in, cs);
|
||||
java.io.BufferedReader br = new java.io.BufferedReader(isr)) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
sb.append(line).append('\n');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 读取文件代码
|
||||
* @param filePath 文件路径
|
||||
|
Reference in New Issue
Block a user