如何用Java创建.in输入文件?测试用例生成遇数值异常求助
问题根源找到了!
你遇到的异常数值问题,核心是Java里OutputStream.write(int)的行为和C++的cout完全不一样:
- C++的
cout是把整数转成人类能看懂的十进制字符串写入文件; - 但
OutputStream.write(int)只把整数的低8位二进制字节直接写进去,所以文件里存的不是文本,而是二进制数据,打开后自然会显示成奇怪的十六进制或者乱码。
给你修正后的Java代码
我帮你写了严格对齐原C++逻辑的版本,用PrintWriter来实现和cout一样的文本输出,同时保留了原代码的随机种子、数值范围这些关键细节:
import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.Random; public class TestCaseGenerator { public static void main(String[] args) throws IOException { // 用PrintWriter实现文本输出,和C++的cout行为一致 try (PrintWriter writer = new PrintWriter(new FileWriter("n1.in"))) { Random rand = new Random(5); // 固定随机种子,和原C++的srand(5)对应,保证测试用例可复现 int t = rand.nextInt(99) + 1; // 生成1~99的整数,对应原代码rand()%99+1 // 原C++的assert检查,用if判断兜底 if (t < 1 || t > 100) { throw new IllegalArgumentException("生成的t超出范围啦!"); } writer.println(t); // 输出t并换行,等价于C++的cout<<t<<endl while (t-- > 0) { int n = rand.nextInt(98) + 3; // 生成3~100的整数,这里修正了原C++代码的小问题(原代码可能生成101触发断言) if (n < 3 || n > 100) { throw new IllegalArgumentException("生成的n超出范围啦!"); } writer.println(n); // 输出n并换行 } } // try-with-resources会自动关闭文件流,不用手动操心 } }
几个关键细节说明
- 随机种子:
new Random(5)和原C++的srand(5)完全对应,这样每次运行生成的测试用例一模一样,方便你调试竞赛题; - 数值范围:原C++的
rand()%99+3其实可能生成101(因为rand()%99最大是98,98+3=101),然后触发assert(n<=100),我改成了rand.nextInt(98)+3,这样n的范围严格是3~100,避免断言错误; - 资源管理:用
try-with-resources语法,Java会自动帮你关闭文件流,不用怕忘记关流导致的资源泄漏; - 文本输出:
PrintWriter.println()会自动把整数转成十进制字符串,还会加换行符,和C++的cout<<...<<endl效果完全一致。
验证方式
运行完代码后,打开生成的n1.in文件,就能看到正常的十进制整数了——第一行是测试用例组数t,后面跟着t行每个测试用例的n值,和原C++代码生成的结果完全匹配。
内容的提问来源于stack exchange,提问作者ritwikshanker
相关产品推荐
相关产品推荐

