You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java printf打印类对象数组仅最后一个索引值可正常输出问题

问题根因

这个异常和printf方法本身无关,核心原因是读取文本文件时没有处理Windows系统的\r回车符,完全匹配你描述的故障表现:

  • Windows环境下文本文件的换行标识为\r\n(回车+换行双字符),你代码中用split("\n")拆分全量文件内容时,除了文件最后一行,其余所有行的末尾都会残留一个\r(ASCII码13,即回车符)。
  • 按你的字段拆分逻辑,description是每行最后一个被拆分出来的字段,因此除了数组最后一个InsuranceCompany对象,其余所有对象的description字段值都会携带这个多余的\r。
  • 回车符\r的输出效果是将光标直接移动到当前行的起始位置,不会触发换行。当你用printf输出带\r的内容时,前面已经打印的公司名、分隔线等内容,会在\r触发光标回退到行首后,被后续输出的内容直接覆盖,视觉上就像没有正常输出对应值;而你用println校验数据时,要么是输出整段内容后直接换行,\r的覆盖效果没有触发,要么是你没注意到内容覆盖的细节,所以误以为数据完全正常。
  • 数组最后一个元素对应文件的最后一行,这一行末尾没有换行符,拆分出的description字段不带\r,因此打印完全正常。

另外你的代码里还有个小问题:printf中使用的大写%S占位符会自动将传入的字符串转为全大写输出,如果不需要这个效果,应该使用小写%s占位符。

修复方案
  1. 修正文件内容拆分逻辑,兼容多系统换行格式,清除残留的\r字符:
    将原代码中拆分数据行的语句
    String[] data = loadDataFromFile(dataFile).split("\n");
    
    替换为
    // 先移除所有\r回车符,再按换行拆分,兼容Windows、Linux、macOS的换行规则
    String[] data = loadDataFromFile(dataFile).replace("\r", "").split("\n");
    
  2. (可选调整)如果不需要自动将打印内容转为全大写,把代码中所有printf里的大写%S占位符替换为小写%s即可,例如:
    // 原语句 System.out.printf("| %-18S | %-28S |%n", selectedCompany.getCompanyName(), selectedCompany.getDescription());
    // 修改为
    System.out.printf("| %-18s | %-28s |%n", selectedCompany.getCompanyName(), selectedCompany.getDescription());
    
    打印险种类型的%15S也对应修改为%15s即可。

修复完成后,传入0到length-2范围的索引调用打印方法,就不会再出现内容被覆盖、输出异常的问题。你之前注释掉的System.out.flush()语句不需要启用,printf遇到%n换行符时会自动刷新输出缓冲区,不存在缓冲区未刷新导致内容不打印的问题。


附问题复现代码:
InsuranceCompany类:

package com.insurance.company;

import java.util.List;

/**
 *
 * @author Lenovo
 */
public class InsuranceCompany {
    private String companyName;
    private String telephone;
    private String webAddress;
    private double brokerPercentage;
    private String description;
    private List<String> insuranceTypes;

    public InsuranceCompany(){}
    public InsuranceCompany(String companyName, String telephone, String webAddress, double brokerPercentage, String description, List<String> insuranceTypes) {
        this.companyName = companyName;
        this.telephone = telephone;
        this.webAddress = webAddress;
        this.brokerPercentage = brokerPercentage;
        this.description = description;
        this.insuranceTypes = insuranceTypes;
    }
    
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(companyName);
        sb.append(" " + telephone);
        sb.append(" " + webAddress);
        for(int i = 0; i < insuranceTypes.size(); i++){
            sb.append(" " + insuranceTypes.get(i));
        }
        sb.append(" " + brokerPercentage);
        sb.append(" " + description);
        return sb.toString();
    }

    public String getCompanyName() {
        return companyName;
    }

    public String getTelephone() {
        return telephone;
    }

    public String getWebAddress() {
        return webAddress;
    }

    public double getBrokerPercentage() {
        return brokerPercentage;
    }

    public String getDescription() {
        return description;
    }

    public List<String> getInsuranceTypes() {
        return insuranceTypes;
    }
    
}

InsurancePortal主类:

package com.insurance.company;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class InsurancePortal {
    //function to load data from file
    private static String loadDataFromFile(String path)throws Exception{
        String data;
        data = new String(Files.readAllBytes(Paths.get(path)));
        return data;
    }
    //function to list all insurance companies
    private static void listInuranceCompanies(InsuranceCompany[] company){
        System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------");
        System.out.printf("| %3s | %-20s | %-111s |%n", "ID", "Company Name", "Cover Types");
        //System.out.flush();
        System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------");
        for(int j = 0; j < company.length; j++){
            System.out.printf("| %3d | %-20s |", j+1, company[j].getCompanyName());
        for(int i = 0; i < 7; i++){
            if(i < company[j].getInsuranceTypes().size()){
                System.out.printf(" %15S", company[j].getInsuranceTypes().get(i));
            }else{
                System.out.printf(" %15s", " ");
            }
        }
        System.out.print(" |\n");
        System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------");
        }
    }
    //function to search cover
    public static void listSingleCompanyDetails(InsuranceCompany selectedCompany){
        System.out.println(selectedCompany.getCompanyName()+"\n--------------------------------------------------");
        //System.out.flush();
        System.out.printf("| %-18S | %-28S |%n", selectedCompany.getCompanyName(), selectedCompany.getDescription());
        //System.out.flush();
        System.out.println("--------------------------------------------------");
        System.out.println("--------------------------------------------------");
        System.out.println("--------------------------------------------------");
        System.out.println("--------------------------------------------------");
        System.out.println("--------------------------------------------------");
    }
    
    public static void main(String arge[]) throws Exception{
        String dataFile = System.getProperty("user.dir") + File.separator + "insurance-data.txt";
        String[] data = loadDataFromFile(dataFile).split("\n");
        /*for(String str: data){
            System.out.println(str);
        }*/
        int rows = data.length;
        InsuranceCompany[] company = new InsuranceCompany[rows];
        //Initialising objects for every row of data in the file
        for(int j = 0; j < rows; j++){
            String row = data[j];
            //System.out.println(row);
            String companyName, telephone, webAddress, description;
            double brokerPercentage;
            List<String> insuranceTypes = new ArrayList<>();
        
            //Splitting for Company Name
            String[] splittedArray = row.split(":", 2);
            companyName = splittedArray[0];
            row = splittedArray[1];
        
            //Splitting for telephone
            splittedArray = row.split(":", 2);
            telephone = splittedArray[0];
            row = splittedArray[1];
            
            //splitting for web address
            splittedArray = row.split(":", 2);
            webAddress = splittedArray[0];
            row = splittedArray[1];
        
            //splitiing for insurance types
            splittedArray = row.split(":", 2);
            String[] insuranceTypeList = splittedArray[0].split(",");
            for(String str : insuranceTypeList){
                insuranceTypes.add(str);
            }
            row = splittedArray[1];
        
            //splitting for broker percentage
            splittedArray = row.split(":", 2);
            brokerPercentage = Double.parseDouble(splittedArray[0]);
            row = splittedArray[1];
        
            //splitting for description
            splittedArray = row.split(":", 2);
            description = splittedArray[0];
            company[j] = new InsuranceCompany(companyName, telephone, webAddress, brokerPercentage, description, insuranceTypes);
        }
        boolean run = true;
        while(run){
            int choice;
            Scanner sc = new Scanner(System.in);
            System.out.print("\nList insurance companies.......1\n"
                             + "Select insurance company.......2\n"
                             + "Search cover...................3\n"
                             + "Exit...........................0\n"
                             + "\nEnter choice:> ");
            choice = sc.nextInt();
            switch(choice){
                case 1 : 
                    listInuranceCompanies(company);
                    break;
                case 2 : 
                    System.out.print("Enter company ID from list [1 - "+(company.length)+"] :> ");
                    int selectedCompany;
                    selectedCompany = sc.nextInt();
                    listSingleCompanyDetails(company[selectedCompany-1]);
                    break;
                case 0 :
                    System.exit(0);
                    break;
                default: System.out.println("Invalid choice!, please try again.");
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Lakshya Sengar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 05:24:14