質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

1078閲覧

Javaの標準入力を変更すると日本語が文字化けする

_noma

総合スコア1

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2023/05/02 01:38

編集2023/05/02 02:44

前提

Javaで、以下のサイトを参考に標準入出力を変えました。
【Java】標準入力&標準出力をJUnitでテストしたい
ですが、入出力のテストを行ったところ、日本語を入力すると出力が文字化けしました。

出力

想定される出力:

abcdあいうえお abcdあいうえお どうして

得られた出力:

abcdBDFHJ abcdBDFHJ どうして

該当のソースコード

Main.java

Java

1package inout; 2 3import java.io.PrintStream; 4import java.util.Scanner; 5 6public class Main { 7 8 public static void main( String[] args) { 9 StandardOutputStream out = new StandardOutputStream(); 10 11 StandardInputStream in = new StandardInputStream(); 12 13 PrintStream defaultOut = System.out; 14 15 System.setOut( out); 16 System.setIn( in); 17 18 in.inputln( "abcdあいうえお"); 19 Scanner scanner = new Scanner( in); 20 String input = scanner.nextLine(); 21 defaultOut.println( input); 22 System.out.println( input); 23 defaultOut.println( out.readLine()); 24 out.append( "どうして"); 25 defaultOut.println( out.readLine()); 26 } 27}

StandardInputStream.java

Java

1package inout; 2 3import java.io.IOException; 4import java.io.InputStream; 5 6/** 7 * 標準入力を変えるためのStream 8 */ 9public class StandardInputStream extends InputStream { 10 /** バッファ */ 11 private StringBuilder buffer = new StringBuilder(); 12 13 /** 改行文字 */ 14 private static String crlf = System.getProperty( "line.separator"); 15 16 /** 17 * 文字列を入力する 18 * @param str 文字列 19 */ 20 public void inputln( String str) { 21 buffer.append( str).append( crlf); 22 } 23 24 @Override 25 public int read() throws IOException { 26 if ( buffer.length() == 0) { 27 return -1; 28 } 29 int result = buffer.charAt( 0); 30 buffer.deleteCharAt( 0); 31 return result; 32 } 33}

StandardOutputStream.java

Java

1package inout; 2 3import java.io.BufferedReader; 4import java.io.ByteArrayOutputStream; 5import java.io.IOException; 6import java.io.PrintStream; 7import java.io.StringReader; 8 9/** 10 * 標準出力を変えるためのStream 11 */ 12public class StandardOutputStream extends PrintStream { 13 private BufferedReader buffer = new BufferedReader( new StringReader( "")); 14 15 public StandardOutputStream() { 16 super( new ByteArrayOutputStream()); 17 } 18 19 /** 20 * 1行文の文字列を読み込む 21 * @return 文字列 22 */ 23 public String readLine() { 24 try { 25 String line = ""; 26 if ( (line = buffer.readLine()) != null) { 27 return line; 28 } 29 buffer = new BufferedReader( new StringReader( out.toString())); 30 (( ByteArrayOutputStream) out).reset(); 31 return buffer.readLine(); 32 } 33 catch ( IOException e) { 34 throw new RuntimeException( e); 35 } 36 } 37}

試したこと

Mainで試したように、StandardOutputStreamの方は単体では日本語を出力できているように見えます。
問題なのは、StandardInputStreamに日本語を入力する方だと思います。

補足情報(FW/ツールのバージョンなど)

OSはWindows11、実行環境はEclipse 2023-03で、JavaSE-11を使用しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

quickquip

2023/05/02 01:46

OSと実行環境(何かのIDEやエディタ上? シェルやプロンプト上? など)を明記した方がよいかと思います
_noma

2023/05/02 02:45

ありがとうございます。追記しました。
guest

回答1

0

ベストアンサー

以下のコードでうまく動くようになりました。
ポイントは、InputStream#read() の返り値はintですが、0-255の範囲と指定されていることです。
ようするに unsigned byte ですが、javaにそのような型がないので int で代用していると思われます。

read() が返すべき値は、文字列のバイト列です。あまりこのあたりに詳しくないので間違っていたらどなたか訂正してください。

package inout; import java.io.IOException; import java.io.InputStream; import java.util.LinkedList; /** * 標準入力を変えるためのStream */ public class StandardInputStream extends InputStream { /** バッファ */ private LinkedList<Byte> buffer = new LinkedList<>(); /** 改行文字 */ private static String crlf = System.getProperty( "line.separator"); /** * 文字列を入力する * @param str 文字列 */ public void inputln( String str) { var appendStr = str + crlf; var byteArray = appendStr.getBytes(); for (byte b : byteArray) { buffer.addLast(Byte.valueOf(b)); } } @Override public int read() throws IOException { if ( buffer.isEmpty()) { return -1; } Byte in = buffer.pollFirst(); return in.intValue(); } }

投稿2023/05/02 02:49

編集2023/05/02 02:57
YakumoSaki

総合スコア2027

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

_noma

2023/05/02 03:51

こちらで試したところ、想定通りに動きました! read()の返り値が限定されているとは知りませんでした。 素早いご回答ありがとうございました!
YakumoSaki

2023/05/02 04:36

お役に立ててよかったです!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問