Javaストリームでの文字列の扱いについて

このQ&Aのポイント
  • Javaのストリームを勉強している際に、文字列の扱いについて疑問が生じました。
  • 具体的には、ユーザが入力した文字をint型の変数に代入する仕組みや、read()メソッドの戻り値について疑問があります。
  • また、出力時に文字として表示するためにchar型にキャストされる仕組みについても教えていただきたいです。
回答を見る
  • ベストアンサー

Java ストリームでの文字列の扱いについて

Javaのストリームを勉強している際に、下記のサンプルソースを見ました。 (ユーザが入力した内容を、1文字ずつそのまま画面に返すプログラムです。) 疑問点があるので教えて下さい。 ===== import java.io.*;  public class Sample{   public static void main(String args[]){   int b;   try{    while((b = System.in.read()) != -1){    System.out.print((char)b); 以下省略 ====== ■疑問箇所1. while((b = System.in.read()) != -1) とありますが、 (1)ユーザが入力した文字(整数ではない)が、何故、int型の変数に代入出来るのでしょうか? (2)read()メソッドはint型の戻り値を持つようですが、EOFの"-1"以外の時は、  どんな数値が返されているのでしょうか?  (read()メソッドは、1文字読み込んで、戻り値でその文字をUnicodeにエンコードした値を返しているとか?) ■疑問箇所2. System.out.print((char)b); とありますが、変数bには数値が入っていると考えられます。 これは、変数bの整数が、(char)でキャストされる事によって、 再び、文字に「変換」されているのでしょうか? 以上、教えて下さい。

  • Java
  • 回答数2
  • ありがとう数0

質問者が選んだベストアンサー

  • ベストアンサー
  • salsberry
  • ベストアンサー率69% (495/711)
回答No.2

>System.out.print((char)b); >とありますが、変数bには数値が入っていると考えられます。 >これは、変数bの整数が、(char)でキャストされる事によって、 >再び、文字に「変換」されているのでしょうか? これはとても手抜きなやり方です。 標準入力から読み込まれた文字列が「1文字=1バイト」で表せる文字だけに限られていてしかもその文字コードがUnicodeの文字コードと一致する場合だけ期待した出力が得られます。 ASCIIの範囲内の英数字や記号類であればこの条件を満たすため、たまたま動いているように見えるだけです。

その他の回答 (1)

  • helonpa
  • ベストアンサー率38% (108/278)
回答No.1

> (1)ユーザが入力した文字(整数ではない)が、何故、int型の変数に代入出来るのでしょうか? http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/index.html http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/io/InputStream.html#read() 「System.in.read()」(InputStream)は標準入力をバイトで扱い、戻り値がint型だからです。 また標準入力は文字とは限りません。 > (2)read()メソッドはint型の戻り値を持つようですが、EOFの"-1"以外の時は、  どんな数値が返されているのでしょうか? リファレンスを読んだ方が正確で分かりやすいですね。 http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/io/InputStream.html#read() > これは、変数bの整数が、(char)でキャストされる事によって、 > 再び、文字に「変換」されているのでしょうか? キャストは単に型を合せるだけですが、文字に変換といえば、まぁそうですね。 http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/io/PrintStream.html#print(char)

関連するQ&A

  • 文字列や文字から整数への変換方法について

    文字列(string型)や文字(char型)から整数(int型など)に変換 する時のルールがよく解りません。 たとえば、キーボードから数字を打って、その入力された数字を 数値として整数型の変数に代入したい場合のやり方です。 ちょっとプログラムを作ってみました。 using System; class clmain { private static void Main() { Console.Write("1桁の整数を入れてね "); char ch = char.Parse(Console.ReadLine()); int by1 = (int)ch; int by2 = (int)char.GetNumericValue(ch); Console.WriteLine("by1 = {0}, by2 = {1}, ch = {1}", by1, by2, ch); Console.Write("整数を入れてね "); string st = Console.ReadLine(); /* by = (int)st; コンパイルエラー */ int by3 = int.Parse(st); Console.WriteLine("by3 = {0}, st = {1}", by3, st); } } まず、char型からint型への変換では、  int型変数=(int)char型変数; はコンパイルは通りますけど、実行すると全く違った値が入って しまいます。たとえば char型変数の値が "1" だと、int型変数には 49 が入ります。 int型変数 = (int)char.GetNumericValue(char型変数); と書いてようやく、思い通りの動きをしてくれます。 また、string型からint型への変換では  int型変数=(int)string型変数; はコンパイルエラーになります。 int型変数 = int.Parse(string型変数); とするとコンパイル出来て正しく動きます。 これで質問ですけど、 (1)なぜstring型とchar型で、int型への変換方法が違うのでしょうか? (2)int型変数=(int)char型変数; とすると、上に書いたように、全く 違った(希望しない)値が代入されてしまいます。これは、どういう 動きをしているのでしょうか? また、これはコンパイルエラーに なりませんけど、どういう時にこの書き方をするのでしょうか? 解る方、お願いします。

  • JAVA テキストからの読み込みについて

    以下はsample121.txtというファイルからデータを読み込むプログラムとして とある本に紹介されていた方法を参考にしたものですが while文の中に1文字目を表示したら、2文字めに移行する指示がなされていないように思い 実際に書いて、実行してみましたところ やはり1文字目だけが延々と羅列される結果となりました。 一文字ずつ順番に読み込むとすれば どこを修正すればいいでしょうか。 よろしくお願いします。 import java.io.FileReader; public class traning7 { /** * @param args */ public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ try { FileReader fw = new FileReader("sample121.txt"); int i = fw.read(); while(i != -1){ char c = (char) i ; System.out.println(c); } System.out.println("ファイルの末尾に到達しました。"); fw.close(); }catch(Exception e){ System.out.println("error"); } } }

    • ベストアンサー
    • Java
  • javaというか文字列について少し質問です><

    javaというか文字列について少し質問です>< javaというか文字列について少し質問です>< お願いします。 シーザー暗号で文字列をずらすためのクラスのメソッドをつくったのですが・・・ String decrypt(String str,int key) { StringBuffer sb = new StringBuffer(); // もしくはStringBuilder for(int i=0;i<str.length();i++){ char c=str.charAt(i); c=(char)((int)c-key); sb.append( c ); } こんな感じなのですがアルファベットの小文字26文字のみとしたいので暗号化や復号化の際に越えてしまう場合はアルファベット内でループさせたいのですがいまいちやり方が浮かびません><越えてしまう場合はzからひいたものを表現させれば良いかと思いやってみたのですが全然違う文字が出てきてしまいました。何かいい方法を教えてください。お願いします><

    • ベストアンサー
    • Java
  • int型での文字列の扱いについて

    整数はint型、文字はchar型を使うのが原則のようですが、 文字はコンピュータの中で数字で扱われていることと、 char型が0~255、int型がそれ以上の範囲の数字を扱えることを考えると 文字を扱う時もint型でかまわないのでは?と思いました。 実際、int型で1文字出力できました。具体的には下です。 int a; a=getchar(); printf("%c\n",a); return 0; しかし、文字列をint型で扱おうとすると、コンパイル時にエラーとなります。 int a[50]="Hello"; printf("%s\n",a); return 0; なぜ、int型では文字列が扱えないのか理解できません。

  • 文字列と整数型について

    はじめまして。 どうしても困っているのでヒントでも良いのでおねがいします。 関数内(func1)で確保した文字列変数のポインタを 別の関数(func2)にポインタ渡しします。 func2内で整数型で計算した結果を引数で示された文字列変数に 代入するというようなことをしたいと思ってます。 ここで、intは4byteとします。 メモリ長だけで見ると、bit[4] = tmp です。 void func1(){ char bit[4]; func2(bit); return; } void func2(char* p){ int tmp = 0x10101100; p = tmp; <---- ??? return; } そこでどのようにすれば、 代入することができるのか分かりません。 以下のような結果になるように代入したいと思っています。 bit[0] = 0x10; bit[1] = 0x10; bit[2] = 0x11; bit[3] = 0x00; 小さな文字列型に整数型をどのように渡せばよいのかが 一番疑問に思っているところです。 整数型に文字列型を代入する場合には 文字列のバイト指定とシフト演算で実現できています。 ヒントでもよいのでお願いします。

  • 文字列

    ・数字文字列を数値化する関数AtoS()を制作する。 書式:short AtoS(char *pStr, int *pRetCode); 引数:char *pStr; 文字列の先頭アドレス    int *pRetCode; 動作の正否を返す 戻り値:pStrを数値化した値 処理: pStrで与えられた文字列をshort型に変換する。 呼び出し側の書式は以下の通りです。 void main(void) {  short val; int code; val = AtoS("1234", & code); printf("%d\n",val); val = AtoS("-789", & code); printf("%d\n", val); } です。 自分自身で、正の整数はできました。見てください。そして、負の整数や、「int *pRetCode」の使い方をおしえてください。 #include <stdio.h> short AtoS(cahr *pStr, int *pRetCode); void main(void) { short val; int code; val = AtoS("1234", & code); printf("%d\n", val); val = AtoS("-789", & code); printf("%d\n", val); } short AtoS("char *pStr, int *pRetCode) { short suu; suu = 0; while("\n" != *pStr) { suu = *pStr - '0' + suu * 10; pStr++;   } return(suu); } までしかできません。どなたか教えてください。  

  • 小文字、大文字、記号をランダム表示

    このプログラムは英大文字をランダムに表示するプログラムなのですが、これを小文字と記号も合わさった形で出力されるように改造するにはどうしたらいいでしょうか。コードを添えて下さると助かります。 import java.util.Random; public class Aruf{ public static void main(String[] args) { //Randomクラスのインスタンス化 Random rnd = new Random(); //変数の宣言 int ran; int a; char c; //10回繰り返す for(int b=0;b<10;b++){ //0~25の乱数を作成 ran = rnd.nextInt(26); //65を足して65~90にする a = 65 + ran; //charに型変換 c = (char)a; //表示 System.out.print(c); } } }

    • ベストアンサー
    • Java
  • Java print()とprintf()について

    JavaのPrintStreamクラスのprint()とprintf()メソッドに関して質問です。 どちらのメソッドもPrintStreamにデータを書き込でいるように思うのですが、print()メソッドには戻り値がないのに対し、printf()メソッドにはPrintStream型の戻り値が存在しているのはなぜでしょうか? どなたかご回答いただければ幸いです。

    • ベストアンサー
    • Java
  • mainから渡した文字列を関数内で書き換え

    非常に基礎的な質問で申し訳ないのですが mainから渡した文字列を関数内で書き換えることができません。 int型の整数やchar型一文字はできるのですが。。。 例えば以下のようなソースでmainのABCをDEFに書き換えたいとき どのようにすればいいのでしょうか。 (関数の戻り値で変更という方法以外で) 以下のソースでは値は書き換わりませんでした。 void func(char *str2) { str2 = "DEF"; } int main() { char str1[20] = "ABC" printf("%s", str1); //ABC func(str1); printf("%s", str1); //DEFになるようにしたい }

  • java

    Base64にエンコードしたものをデコードするプログラムです。(汎用性が低いのは仕様です)コンパイルは通ったのですが、実行したら以下のエラーが出てきました。 C:\Users\Owner\Documents\javadev>java Base64Decode2 hello.dat hello2.txt java.lang.ArrayIndexOutOfBoundsException: 97 at Base64Decode2.decode(Base64Decode2.java:51) at Base64Decode2.main(Base64Decode2.java:23) 指定の行を見ても原因がよく分かりません。とても初歩的な質問なのかもしれませんが、お願いします。 以下がプログラムコードです import java.io.*; public class Base64Decode2 { public static void main(String[] args) { // 変換テーブル char[] table = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; InputStream in = null; // 入力データ OutputStream out = null; // 出力先 try { in = new FileInputStream(args[0]); out = new FileOutputStream(args[1]); char[] cs; while ((cs=read4(in)) != null) { int[] buf = decode(cs, table);//ここが問題? for (int i=0; i<buf.length; i++) { System.out.print(buf[i]+", "); } System.out.println(); int[] buf2 = convert6to8(buf); write3(out, buf2); } } catch (Exception e) { e.printStackTrace(); // 例外の情報を表示する } finally { // in, out を閉じる try { in.close(); out.close(); } catch (Exception e) { } } } /** * 8ビットの2進数の列を復号化する. * @param cs * @param table 符号テーブル * @return */ public static int[] decode(char[] cs, char[] table) { int[] buf = new int[cs.length]; for (int i=0; i<buf.length; i++) { buf[i] = table[cs[i]];//ここが問題? } return buf; } public static int[] convert6to8(int[] buf) { String b; int[] buf2; if (buf.length == 2) { b = toBinary(buf[0], 6); buf2 = new int[1]; buf2[0] = fromBinary(b.substring(0, 8)); } else if (buf.length == 3) { b = toBinary(buf[0], 6) + toBinary(buf[1], 6); buf2 = new int[2]; buf2[0] = fromBinary(b.substring(0, 8)); buf2[1] = fromBinary(b.substring(8, 16)); } else { b = toBinary(buf[0], 6) + toBinary(buf[1], 6) + toBinary(buf[2], 6); buf2 = new int[3]; buf2[0] = fromBinary(b.substring(0, 8)); buf2[1] = fromBinary(b.substring(8, 16)); buf2[2] = fromBinary(b.substring(16, 24)); } return buf2; } /** * バイト列 bt の数を順に出力する. * @param bt 数の配列。長さは 3以下. 各数は8ビットの整数 */ public static void write3(OutputStream out, int[] bt) throws IOException { for (int i=0; i<3; i++) { if (i<bt.length) { out.write(bt[i]); } } } /** * in から文字を最大4つ読み出す. * @param in 入力ストリーム * @return 文字の配列。配列長は最大4. 入力終了したときには null を返す. */ public static char[] read4(InputStream in) throws IOException { char[] bs; int n0=in.read(); int n1=in.read(); int n2=in.read(); int n3=in.read(); if (n0 < 0) { // 読み込み終了 bs = null; } else if (n2 < 0 || (char) n2=='=') { bs = new char[2]; bs[0] = (char) n0; bs[1] = (char) n1; } else if (n3 < 0 || (char) n3=='=') { bs = new char[3]; bs[0] = (char) n0; bs[1] = (char) n1; bs[2] = (char) n2; } else { bs = new char[4]; bs[0] = (char) n0; bs[1] = (char) n1; bs[2] = (char) n2; bs[3] = (char) n3; } return bs; } /** * 数を読み取って、nビットの2進数を表す文字列に変換する * @param bt 1バイトの数 * @param n 2進数のビット数 * @return 2進数を表す文字列 */ public static String toBinary(int bt, int n) { String s = Integer.toBinaryString(bt); for (int i=s.length(); i<n; i++) { s = "0" + s; } return s; } /** * 2進数を表す文字列を数に変換する * @param b 2進数を表す文字列 * @return b が表す数 */ public static int fromBinary(String b) { return Integer.parseInt(b, 2); } }

    • ベストアンサー
    • Java

専門家に質問してみよう