【修改】 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) {
|
public static String run_codes(String pathC, String code, String input, String standard, String text) {
|
||||||
try {
|
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);
|
File workDir = new File(pathC);
|
||||||
if (!workDir.exists()) workDir.mkdirs();
|
if (!workDir.exists()) workDir.mkdirs();
|
||||||
|
|
||||||
boolean isWindows = System.getProperty("os.name").toLowerCase().contains("win");
|
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 programC = new File(workDir, "program.c").getAbsolutePath();
|
||||||
String programOut = new File(workDir, isWindows ? "program.exe" : "program.out").getAbsolutePath();
|
String programOut = new File(workDir, isWindows ? "program.exe" : "program.out").getAbsolutePath();
|
||||||
|
|
||||||
// 写入 C 源码
|
// 写入 C 源码(按指定字符集)
|
||||||
try (FileWriter writer = new FileWriter(programC)) {
|
try (java.io.OutputStream os = new java.io.FileOutputStream(programC);
|
||||||
writer.write(code);
|
java.io.OutputStreamWriter writer = new java.io.OutputStreamWriter(os, charset)) {
|
||||||
|
writer.write(code == null ? "" : code);
|
||||||
|
writer.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
// jar 所在目录
|
// jar 所在目录
|
||||||
@@ -149,21 +153,15 @@ public class JudgementCUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 编译命令
|
// 编译命令
|
||||||
ProcessBuilder compileBuilder;
|
ProcessBuilder compileBuilder = (stdFlag == null)
|
||||||
if (stdFlag == null) {
|
? new ProcessBuilder(tccExe.getAbsolutePath(), programC, "-o", programOut)
|
||||||
compileBuilder = new ProcessBuilder(tccExe.getAbsolutePath(), programC, "-o", programOut);
|
: new ProcessBuilder(tccExe.getAbsolutePath(), stdFlag, programC, "-o", programOut);
|
||||||
} else {
|
|
||||||
compileBuilder = new ProcessBuilder(tccExe.getAbsolutePath(), stdFlag, programC, "-o", programOut);
|
|
||||||
}
|
|
||||||
compileBuilder.directory(workDir);
|
compileBuilder.directory(workDir);
|
||||||
compileBuilder.redirectErrorStream(true);
|
compileBuilder.redirectErrorStream(true);
|
||||||
|
|
||||||
Process compileProcess = compileBuilder.start();
|
Process compileProcess = compileBuilder.start();
|
||||||
StringBuilder compileOutput = new StringBuilder();
|
String compileOutput = readAll(compileProcess.getInputStream(), charset);
|
||||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(compileProcess.getInputStream(), StandardCharsets.UTF_8))) {
|
|
||||||
String line;
|
|
||||||
while ((line = br.readLine()) != null) compileOutput.append(line).append("\n");
|
|
||||||
}
|
|
||||||
int compileResult = compileProcess.waitFor();
|
int compileResult = compileProcess.waitFor();
|
||||||
if (compileResult != 0 || !new File(programOut).exists()) {
|
if (compileResult != 0 || !new File(programOut).exists()) {
|
||||||
return "❌ 编译失败,输出:\n" + compileOutput;
|
return "❌ 编译失败,输出:\n" + compileOutput;
|
||||||
@@ -176,29 +174,25 @@ public class JudgementCUtils
|
|||||||
Process runProcess = runBuilder.start();
|
Process runProcess = runBuilder.start();
|
||||||
|
|
||||||
if (hasInput && input != null) {
|
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.write(input);
|
||||||
bw.newLine();
|
bw.newLine();
|
||||||
bw.flush();
|
bw.flush();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// 关闭输入流,避免某些程序等待 STDIN
|
||||||
|
try { runProcess.getOutputStream().close(); } catch (Exception ignore) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
java.util.concurrent.ExecutorService executor = java.util.concurrent.Executors.newSingleThreadExecutor();
|
||||||
Future<String> future = executor.submit(() -> {
|
java.util.concurrent.Future<String> future = executor.submit(() -> readAll(runProcess.getInputStream(), charset));
|
||||||
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();
|
|
||||||
});
|
|
||||||
|
|
||||||
String output;
|
String output;
|
||||||
try {
|
try {
|
||||||
output = future.get(5, TimeUnit.SECONDS);
|
output = future.get(5, java.util.concurrent.TimeUnit.SECONDS);
|
||||||
} catch (TimeoutException e) {
|
} catch (java.util.concurrent.TimeoutException e) {
|
||||||
runProcess.destroyForcibly();
|
runProcess.destroyForcibly();
|
||||||
future.cancel(true);
|
future.cancel(true);
|
||||||
output = "⏰ 程序运行超时(超过 5 秒)";
|
output = "⏰ 程序运行超时(超过 5 秒)";
|
||||||
@@ -213,6 +207,31 @@ public class JudgementCUtils
|
|||||||
return "运行 C 代码时出错:" + ex.getMessage();
|
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 文件路径
|
* @param filePath 文件路径
|
||||||
|
Reference in New Issue
Block a user