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

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

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

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

解決済

formatでの空白表示

oimo0505
oimo0505

総合スコア22

Java

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

2回答

0リアクション

0クリップ

477閲覧

投稿2022/09/12 10:52

編集2022/09/12 11:26

前提

 現在お小遣い帳を作成しており、入力した値をObject型の配列に格納し、名目を判別後各Wallet,FoodExpences,BookFee,DailyCost型(各クラスはスーパークラスItemのサブクラス)にキャストしたものを表に表示させようとしています。
(残額の行はまだ計算式を書いていないためずっと空白のままです。)
表はハイフンなどを用いて自作の枠組みを作っているのですが、表の枠を一定の大きさで保つために入力した値のByte数を判定するメソッドを用い、(表の枠の大きさ)ー(入力した値のByte数)を計算しformatを用いてその数だけ空白を値の右側に出力しようとしています。AddSort2クラスで作っている枠に最終的に合わせようと思っています。

 しかし、収入、支出の行がByte数を判定したものを出力した場合予想通りの値(例:全角で20000と入力されていれば10)が出力されたのですが、formatを用い表形式で出力しようとした際に、入力した値の桁数が違う場合に出力される空白の数が変わり表の枠(|部分)がガタガタになってしまいます。
formatに関して詳しく調べたつもりなのですがどうしてこのような問題が発生してしまうかわからなかったため質問させていただきました。説明が長くなってしまい申し訳ございません。よろしくお願いします。

csvファイルの内容

お財布 収 20000 N/A
食費    支 2000 N/A
書籍    支 1500 N/A
日用品費 支 500    N/A
お財布 収 5000 N/A
お財布 収 1    N/A
お財布 収 10000 N/A
食費    支 10000 N/A

追記:
表での表示はターミナル内で行いたいと考えています。

実現したいこと

(表の枠の大きさ)ー(入力した値のByte数)の差だけ空白を値の右側に出力

発生している問題・エラーメッセージ

空白の数の計算まではできているのだがその数だけの空白の出力ができていないため表の縦に分割する場所がガタガタになっている。

該当のソースコード

AddSort2.java

Java

package bookmoney; public class AddSort2 { private int balance = 0; public void getTableParts(Object [] itemArray) { String format = "|%1$-10s|%2$-12s|%3$-12s|%4$-4s|%5$-20s|\n"; System.out.format(format, "名目", "収入", "支出", "残額", "補足"); System.out.println("-------------+--------------+--------------+------+-----------------------"); for (int i = 0; i < itemArray.length; i++) { if (itemArray[i] instanceof Wallet) { Wallet wallet = (Wallet)itemArray[i]; System.out.println(wallet.getTableParts()); System.out.println("-------------+--------------+--------------+------+-----------------------"); } else if (itemArray[i] instanceof FoodExpences) { FoodExpences foodExpences = (FoodExpences)itemArray[i]; System.out.println(foodExpences.getTableParts()); System.out.println("-------------+--------------+--------------+------+-----------------------"); } else if (itemArray[i] instanceof BookFee) { BookFee bookFee = (BookFee) itemArray[i]; System.out.println(bookFee.getTableParts()); System.out.println("-------------+--------------+--------------+------+-----------------------"); } else if (itemArray[i] instanceof DailyCost) { DailyCost dailyCost = (DailyCost) itemArray[i]; System.out.println(dailyCost.getTableParts()); System.out.println("-------------+--------------+--------------+------+-----------------------"); } } } }

Wallet.java  これと型の名前だけが違うクラスが各名目ごとにあります。

Java

package bookmoney; import java.util.*; public class Wallet extends Item{ private String wallet; public Wallet (String name, String flag, String amount, String wallet) { super(name, flag, amount); this.name = getName(); this.flag = getFlag(); this.amount = getAmount(); this.wallet = wallet; } public String getWallet() { return this.wallet; } public String getTableParts() { String lineTable = null; HanZen2 han1Zen2 = new HanZen2(); String name = this.name; String flag = this.flag; String amountStr = this.amount; String note = this.wallet; String amount = ""; String in = ""; String out = ""; if (flag.equals("収")) { in = amountStr; } else if (flag.equals("支")) { out = amountStr; } int nameBlank = 15 - han1Zen2.getHan1Zen2(name); int inBlank = 14 - han1Zen2.getHan1Zen2(in); int outBlank = 14 - han1Zen2.getHan1Zen2(out); int noteBlank = 25- han1Zen2.getHan1Zen2(note); // String inBlankStr = String.valueOf(inBlank); String namelineTable = name.format(("|%-" + nameBlank + "s"), name); String inlineTable = in.format(("|%-" + inBlank + "s" ), in); String outlineTable = out.format(("|%-" + outBlank + "s" ), out); String amountTable = amount.format(("|%-6s"), amount); String notelineTable = note.format(("|%-" + noteBlank + "s|" ), note); lineTable = namelineTable + inlineTable + outlineTable + amountTable + notelineTable; // lineTable = String.valueOf(inBlank ); return lineTable; } }

DataLoad2.java クラスを判定しキャストさせる

Java

package bookmoney; import java.io.BufferedReader; import java.io.FileReader; import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; public class DataLoad2 { private Object [] itemArray; public Object[] dataLoadMethod() { try (BufferedReader br = new BufferedReader(new FileReader("bookmoney/PocketMoney.csv"))) { int count = 0; //ファイルの行数取得 Path file = Paths.get("bookmoney/PocketMoney.csv"); long lineNum = Files.lines(file).count(); int lineInt = Math.toIntExact(lineNum); itemArray = new Object[lineInt]; String s; while ((s = br.readLine()) != null) { // 読み込んだ行を、「,」で分割する String data[] = s.split(","); if (data[0].equals("お財布")) { itemArray[count] = new Wallet(data[0], data[1], data[2], data[3]); } else if (data[0].equals("食費")) { itemArray[count] = new FoodExpences(data[0], data[1], data[2], data[3]); } else if (data[0].equals("書籍")) { itemArray[count] = new BookFee(data[0], data[1], data[2], data[3]); } else if (data[0].equals("日用品費")) { itemArray[count] = new DailyCost(data[0], data[1], data[2], data[3]); } count++; } } catch (IOException e) { System.out.println("入出力エラーです"); } return itemArray; } }

HanZen2.java 値のByte数取得

Java

package bookmoney; public class HanZen2 { public static int getHan1Zen2(String str) { //戻り値 int ret = 0; //全角半角判定 char [] c = str.toCharArray(); for (int i = 0; i < c.length; i++) { if (String.valueOf(c[i]).getBytes().length <= 1) { ret += 1; //半角なら+1 } else { ret += 2;//全角なら+2 } } return ret; } }

Item.java

Java

package bookmoney; public class Item { protected String name; protected String flag; protected String amount; public Item (String name, String flag, String amount) { this.name = name; this.flag = flag; this.amount = amount; } //getter public String getName() { return this.name; } public String getFlag() { return this.flag; } public String getAmount() { return this.amount; } }

実行するクラス(該当箇所を抜粋しています)

Java

case 1: System.out.println("《データロード》"); DataLoad2 data = new DataLoad2(); itemArray = data.dataLoadMethod(); System.out.println("データロードが完了しました。"); break; case 2: System.out.println("《表表示》"); AddSort2 addSort2 = new AddSort2(); addSort2.getTableParts(itemArray); break;

試したこと

空白の出力数を確認したが予想通りの値が出力された

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

IntelliJを使用しています。

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

m.ts10806

2022/09/12 10:57

CSVなら カンマ区切りでは。(もしくはタブ区切り) 空白であわせるというのは聞いたことがないです。
oimo0505

2022/09/12 11:18 編集

m.ts10806様 コメントありがとうございます。 説明で不足していたのですがcsvファイルに出力する際はカンマ区切りで出力するようにしています。 その後ターミナル内で自作の枠組みを作り表を表示させようと思っていて、splitでカンマごとに配列に格納しそれを表示させる際に次の配列を出力するまでの空白を表示させようと考えています。 例えば、少しずれていますがこんな感じです 名目    |収入   |支出    |補足 ------------------------------------------------------------- array[0] |array[1] |array[2] |array[3]
m.ts10806

2022/09/12 11:19

分かりやすいように追記してもらったらと。 ただ、ターミナルでレイアウト調整はかなり困難を極めると思います。 文字数だけでなく全角半角で違いますし、ターミナルのフォントとかでも容赦なくずれます。 GuiもしくはWebで画面表示した方が良いと思います。
dodox86

2022/09/12 11:21

> 空白であわせるというのは聞いたことがないです。 質問本文中の説明が長くて正直、私などは要旨を把握しかねているのですが、各項目の文字列を固定長にして、指定文字数に満たない部分は空白で埋めたいということでしょうかね。 そうであれば、一部の固定長レコードのフォーマットなどで存在することもありますね。
dodox86

2022/09/12 11:23

ああ、単にターミナル上での表示だけのお話なのですね。
oimo0505

2022/09/12 11:25

ご指摘ありがとうございます。質問の方に追記させていただきます。 半角全角の問題の方は判定メソッドを作成することで解決したと考えていたのですが、format作成の段階で計算した数値通りにならないため質問させていただきました。 フォントが原因の可能性があるのは初耳で気にもしていませんでした、、、。 ターミナル内での出力が要件になっているためどうしても解決しないといけないんですよね、、
dodox86

2022/09/12 11:29

あと、見た目の全角文字が2バイトとは限らないですよ。StringをgetBytes()するときの文字コードによります。シフトJISとUTF-8の違いを確認してみてください。
oimo0505

2022/09/12 11:30

dodox86様 コメントありがとうございます。 >各項目の文字列を固定長にして、指定文字数に満たない部分は空白で埋めたいということでしょうかね。 その通りです。語彙力がないせいで説明が長くなってしまい申し訳ございません。
Crimson_Tide

2022/09/12 13:40

https://teratail.com/questions/347729 UTF-8前提ですが、上記回答が多少参考になるかもしれません。 質問のソースの修正の為、コードが読みにくいかもしれません。 指摘があるように、ますば等倍フォントで表示されているか確認してみるのがいいと思います。
oimo0505

2022/09/12 13:53

Crimson_Tide様 コメントありがとうございます。 自己解決してしまったのですが、等倍フォントについても確認してみたいと思います!
jimbe

2022/09/12 16:52

ただのツッコミですが。 >Wallet.java  これと型の名前だけが違うクラスが各名目ごとにあります 分ける意味ありませんね。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Java

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