Scala中的文件读写-成绩分析

30 阅读6分钟

Scala 文件读写与成绩分析

1. 基础文件读取与成绩解析

1.1 读取成绩文件并简单显示

package ex_score

import scala.io.Source
import scala.util.{Try, Using}

object ScoreAnalyzerBasic {
  
  def main(args: Array[String]): Unit = {
    // 方法1:基本读取
    readAndDisplayScores("score.txt")
    
    // 方法2:使用资源管理
    readScoresSafely("score.txt") match {
      case scala.util.Success(scores) => 
        println(s"成功读取 ${scores.length} 条成绩记录")
        displayScores(scores)
      case scala.util.Failure(exception) =>
        println(s"读取失败: ${exception.getMessage}")
    }
  }
  
  // 基本读取方法
  def readAndDisplayScores(filePath: String): Unit = {
    println("=== 学生成绩单 ===")
    
    val source = Source.fromFile(filePath, "UTF-8")
    try {
      val lines = source.getLines().toList
      
      // 打印标题行
      if (lines.nonEmpty) {
        println("标题: " + lines.head)
        println("-" * 40)
      }
      
      // 打印学生成绩
      lines.tail.foreach(println)
      
    } finally {
      source.close()
    }
  }
  
  // 安全的读取方法
  def readScoresSafely(filePath: String): Try[List[String]] = {
    Using(Source.fromFile(filePath, "UTF-8")) { source =>
      source.getLines().toList
    }
  }
  
  def displayScores(lines: List[String]): Unit = {
    if (lines.nonEmpty) {
      println("成绩数据:")
      lines.zipWithIndex.foreach { case (line, index) =>
        println(s"${index + 1}. $line")
      }
    }
  }
}

2. 完整成绩分析系统

2.1 定义数据模型

package ex_score

// 学生成绩数据类
case class StudentScore(
  name: String,
  chinese: Int,
  math: Int,
  english: Int
) {
  // 计算总分
  def totalScore: Int = chinese + math + english
  
  // 计算平均分
  def averageScore: Double = totalScore / 3.0
  
  // 计算单科等级
  def getGrade(score: Int): String = score match {
    case s if s >= 90 => "A"
    case s if s >= 80 => "B"
    case s if s >= 70 => "C"
    case s if s >= 60 => "D"
    case _ => "F"
  }
  
  def chineseGrade: String = getGrade(chinese)
  def mathGrade: String = getGrade(math)
  def englishGrade: String = getGrade(english)
  
  // 总体等级
  def overallGrade: String = getGrade(averageScore.toInt)
  
  override def toString: String = {
    f"$name%-8s 语文:$chinese%3d($chineseGrade) 数学:$math%3d($mathGrade) 英语:$english%3d($englishGrade) " +
    f"总分:$totalScore%3d 平均分:${averageScore}%.1f 总评:$overallGrade"
  }
}

// 班级统计信息
case class ClassStatistics(
  subjectAverages: Map[String, Double],
  topStudents: List[StudentScore],
  gradeDistribution: Map[String, Int],
  totalStudents: Int
)

2.2 成绩解析器

package ex_score

import scala.io.Source
import scala.util.{Try, Success, Failure}

object ScoreParser {
  
  // 解析一行成绩数据
  def parseScoreLine(line: String): Option[StudentScore] = {
    try {
      // 分割字符串:姓名:语文,数学,英语
      val parts = line.split(":")  // 注意:使用中文冒号
      if (parts.length != 2) return None
      
      val name = parts(0).trim
      val scoreStr = parts(1).trim
      
      // 分割成绩:87,92,88
      val scores = scoreStr.split(",")  // 注意:使用中文逗号
      if (scores.length != 3) return None
      
      Some(StudentScore(
        name = name,
        chinese = scores(0).trim.toInt,
        math = scores(1).trim.toInt,
        english = scores(2).trim.toInt
      ))
    } catch {
      case e: Exception =>
        println(s"解析行失败 '$line': ${e.getMessage}")
        None
    }
  }
  
  // 读取并解析整个文件
  def readAndParseScores(filePath: String): Try[List[StudentScore]] = {
    Try {
      val source = Source.fromFile(filePath, "UTF-8")
      try {
        val lines = source.getLines().toList
        
        if (lines.isEmpty) {
          throw new IllegalArgumentException("文件为空")
        }
        
        // 跳过标题行,解析学生成绩
        val studentScores = lines.tail
          .filter(_.trim.nonEmpty)  // 过滤空行
          .flatMap(parseScoreLine)   // 解析每行
        
        if (studentScores.isEmpty) {
          throw new IllegalArgumentException("未找到有效的成绩数据")
        }
        
        studentScores
      } finally {
        source.close()
      }
    }
  }
  
  // 验证成绩数据
  def validateScores(scores: List[StudentScore]): List[String] = {
    scores.flatMap { score =>
      var errors = List[String]()
      
      // 检查成绩范围
      def validateSubject(subject: String, scoreValue: Int): Unit = {
        if (scoreValue < 0 || scoreValue > 100) {
          errors :+= s"${score.name}${subject}成绩异常: $scoreValue"
        }
      }
      
      validateSubject("语文", score.chinese)
      validateSubject("数学", score.math)
      validateSubject("英语", score.english)
      
      errors
    }
  }
}

2.3 成绩统计分析

package ex_score

import scala.math.Ordering

object ScoreAnalyzer {
  
  // 1. 计算单科平均分
  def calculateSubjectAverages(scores: List[StudentScore]): Map[String, Double] = {
    if (scores.isEmpty) return Map.empty
    
    val chineseAvg = scores.map(_.chinese).sum.toDouble / scores.length
    val mathAvg = scores.map(_.math).sum.toDouble / scores.length
    val englishAvg = scores.map(_.english).sum.toDouble / scores.length
    
    Map(
      "语文" -> chineseAvg,
      "数学" -> mathAvg,
      "英语" -> englishAvg
    )
  }
  
  // 2. 按总分排名
  def rankByTotalScore(scores: List[StudentScore]): List[StudentScore] = {
    scores.sortBy(s => (-s.totalScore, s.name))
  }
  
  // 3. 按单科排名
  def rankBySubject(scores: List[StudentScore], subject: String): List[(String, Int, Int)] = {
    val ranked = subject.toLowerCase match {
      case "语文" => scores.sortBy(s => (-s.chinese, s.name))
      case "数学" => scores.sortBy(s => (-s.math, s.name))
      case "英语" => scores.sortBy(s => (-s.english, s.name))
      case _ => scores
    }
    
    ranked.zipWithIndex.map { case (score, rank) =>
      val subjectScore = subject.toLowerCase match {
        case "语文" => score.chinese
        case "数学" => score.math
        case "英语" => score.english
        case _ => 0
      }
      (score.name, subjectScore, rank + 1)
    }
  }
  
  // 4. 计算各分数段人数
  def calculateScoreRanges(scores: List[StudentScore]): Map[String, Map[String, Int]] = {
    def countByGrade(subjectScores: List[Int]): Map[String, Int] = {
      val grades = subjectScores.map { score =>
        score match {
          case s if s >= 90 => "优秀(90-100)"
          case s if s >= 80 => "良好(80-89)"
          case s if s >= 70 => "中等(70-79)"
          case s if s >= 60 => "及格(60-69)"
          case _ => "不及格(0-59)"
        }
      }
      
      grades.groupBy(identity).view.mapValues(_.size).toMap
    }
    
    Map(
      "语文" -> countByGrade(scores.map(_.chinese)),
      "数学" -> countByGrade(scores.map(_.math)),
      "英语" -> countByGrade(scores.map(_.english))
    )
  }
  
  // 5. 查找优秀学生(各科都>=85)
  def findExcellentStudents(scores: List[StudentScore]): List[StudentScore] = {
    scores.filter { s =>
      s.chinese >= 85 && s.math >= 85 && s.english >= 85
    }
  }
  
  // 6. 查找需要关注的学生(有不及格科目)
  def findStudentsNeedingAttention(scores: List[StudentScore]): List[(StudentScore, List[String])] = {
    scores.flatMap { s =>
      val failingSubjects = List(
        if (s.chinese < 60) Some("语文") else None,
        if (s.math < 60) Some("数学") else None,
        if (s.english < 60) Some("英语") else None
      ).flatten
      
      if (failingSubjects.nonEmpty) {
        Some((s, failingSubjects))
      } else {
        None
      }
    }
  }
  
  // 7. 计算班级整体统计
  def calculateClassStatistics(scores: List[StudentScore]): ClassStatistics = {
    val subjectAverages = calculateSubjectAverages(scores)
    val topStudents = rankByTotalScore(scores).take(3)
    
    // 计算等级分布
    val grades = scores.map(_.overallGrade)
    val gradeDistribution = grades.groupBy(identity).view.mapValues(_.size).toMap
    
    ClassStatistics(
      subjectAverages = subjectAverages,
      topStudents = topStudents,
      gradeDistribution = gradeDistribution,
      totalStudents = scores.length
    )
  }
}

2.4 成绩报告生成

package ex_score

import java.io.{PrintWriter, File}
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

object ScoreReportGenerator {
  
  // 生成文本报告
  def generateTextReport(
    scores: List[StudentScore],
    outputPath: String = "成绩分析报告.txt"
  ): Unit = {
    
    val writer = new PrintWriter(new File(outputPath), "UTF-8")
    
    try {
      // 报告头部
      writer.println("=" * 60)
      writer.println("                学生成绩分析报告")
      writer.println("=" * 60)
      writer.println(s"生成时间: ${LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))}")
      writer.println(s"分析人数: ${scores.length} 人")
      writer.println()
      
      // 1. 学生成绩详情
      writer.println("一、学生成绩详情")
      writer.println("-" * 60)
      writer.println(f"${"姓名"}%-8s ${"语文"}%6s ${"数学"}%6s ${"英语"}%6s ${"总分"}%6s ${"平均分"}%8s ${"等级"}%4s")
      writer.println("-" * 60)
      
      val rankedScores = ScoreAnalyzer.rankByTotalScore(scores)
      rankedScores.foreach { score =>
        writer.println(f"${score.name}%-8s ${score.chinese}%6d ${score.math}%6d ${score.english}%6d " +
                      f"${score.totalScore}%6d ${score.averageScore}%8.1f ${score.overallGrade}%4s")
      }
      writer.println()
      
      // 2. 科目平均分
      writer.println("二、各科目平均分")
      writer.println("-" * 60)
      val subjectAverages = ScoreAnalyzer.calculateSubjectAverages(scores)
      subjectAverages.foreach { case (subject, avg) =>
        writer.println(f"$subject%4s: ${avg}%.2f 分")
      }
      writer.println()
      
      // 3. 分数段统计
      writer.println("三、各科目分数段统计")
      writer.println("-" * 60)
      val scoreRanges = ScoreAnalyzer.calculateScoreRanges(scores)
      scoreRanges.foreach { case (subject, ranges) =>
        writer.println(s"$subject:")
        ranges.toList.sortBy(_._1).foreach { case (range, count) =>
          writer.println(f"  $range%-12s: $count%2d 人")
        }
      }
      writer.println()
      
      // 4. 优秀学生
      writer.println("四、优秀学生(各科≥85分)")
      writer.println("-" * 60)
      val excellentStudents = ScoreAnalyzer.findExcellentStudents(scores)
      if (excellentStudents.isEmpty) {
        writer.println("暂无")
      } else {
        excellentStudents.foreach { s =>
          writer.println(s"${s.name}:语文${s.chinese} 数学${s.math} 英语${s.english} 总分${s.totalScore}")
        }
      }
      writer.println()
      
      // 5. 需要关注的学生
      writer.println("五、需要关注的学生(有不及格科目)")
      writer.println("-" * 60)
      val studentsNeedingAttention = ScoreAnalyzer.findStudentsNeedingAttention(scores)
      if (studentsNeedingAttention.isEmpty) {
        writer.println("无")
      } else {
        studentsNeedingAttention.foreach { case (student, subjects) =>
          writer.println(s"${student.name}:不及格科目:${subjects.mkString("、")}")
        }
      }
      writer.println()
      
      // 6. 前三名学生
      writer.println("六、总分前三名学生")
      writer.println("-" * 60)
      val topThree = rankedScores.take(3)
      topThree.zipWithIndex.foreach { case (student, index) =>
        writer.println(f"第${index + 1}名:${student.name}%-8s 总分:${student.totalScore}%3d")
      }
      
      // 报告尾部
      writer.println()
      writer.println("=" * 60)
      writer.println("报告结束")
      
    } finally {
      writer.close()
    }
  }
  
  // 生成HTML报告
  def generateHtmlReport(
    scores: List[StudentScore],
    outputPath: String = "成绩分析报告.html"
  ): Unit = {
    
    val writer = new PrintWriter(new File(outputPath), "UTF-8")
    
    try {
      val rankedScores = ScoreAnalyzer.rankByTotalScore(scores)
      val subjectAverages = ScoreAnalyzer.calculateSubjectAverages(scores)
      val topThree = rankedScores.take(3)
      
      writer.println("""<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>学生成绩分析报告</title>
    <style>
        body { font-family: 'Microsoft YaHei', Arial, sans-serif; margin: 40px; background-color: #f5f5f5; }
        .container { max-width: 1200px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; box-shadow: 0 0 20px rgba(0,0,0,0.1); }
        h1 { color: #2c3e50; text-align: center; border-bottom: 3px solid #3498db; padding-bottom: 15px; }
        h2 { color: #3498db; border-left: 5px solid #3498db; padding-left: 15px; }
        table { width: 100%; border-collapse: collapse; margin: 20px 0; }
        th { background-color: #3498db; color: white; padding: 12px; text-align: center; }
        td { padding: 10px; border: 1px solid #ddd; text-align: center; }
        tr:nth-child(even) { background-color: #f9f9f9; }
        tr:hover { background-color: #f1f1f1; }
        .excellent { background-color: #d4edda !important; }
        .warning { background-color: #fff3cd !important; }
        .danger { background-color: #f8d7da !important; }
        .highlight { background-color: #e3f2fd; font-weight: bold; }
        .stat-box { display: inline-block; background: #e8f4fc; padding: 15px; margin: 10px; border-radius: 5px; min-width: 200px; }
        .stat-box h3 { margin-top: 0; color: #2980b9; }
        .medal { display: inline-block; width: 30px; height: 30px; line-height: 30px; border-radius: 50%; color: white; font-weight: bold; margin-right: 10px; }
        .gold { background: #FFD700; }
        .silver { background: #C0C0C0; }
        .bronze { background: #CD7F32; }
        .footer { text-align: center; margin-top: 30px; color: #7f8c8d; font-size: 14px; }
    </style>
</head>
<body>
    <div class="container">""")
      
      // 报告头部
      writer.println(s"""
        <h1>学生成绩分析报告</h1>
        <div style="text-align: center; color: #666; margin-bottom: 30px;">
            生成时间: ${LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss"))} &nbsp;|&nbsp;
            分析人数: ${scores.length} 人
        </div>""")
      
      // 关键统计数据
      writer.println("""
        <div style="text-align: center;">
            <div class="stat-box">
                <h3>班级平均分</h3>""")
      
      subjectAverages.foreach { case (subject, avg) =>
        writer.println(s"<div>${subject}: <strong>${avg.formatted("%.2f")}</strong> 分</div>")
      }
      
      writer.println(s"""
            </div>
            <div class="stat-box">
                <h3>前三名</h3>""")
      
      topThree.zipWithIndex.foreach { case (student, index) =>
        val medalClass = index match {
          case 0 => "gold"
          case 1 => "silver"
          case 2 => "bronze"
        }
        writer.println(s"""<div><span class="medal $medalClass">${index + 1}</span>
                          ${student.name}: <strong>${student.totalScore}</strong> 分</div>""")
      }
      
      writer.println("""
            </div>
        </div>""")
      
      // 成绩表格
      writer.println("""
        <h2>学生成绩排名表</h2>
        <table>
            <thead>
                <tr>
                    <th>排名</th>
                    <th>姓名</th>
                    <th>语文</th>
                    <th>数学</th>
                    <th>英语</th>
                    <th>总分</th>
                    <th>平均分</th>
                    <th>等级</th>
                </tr>
            </thead>
            <tbody>""")
      
      rankedScores.zipWithIndex.foreach { case (student, index) =>
        val rowClass = {
          if (student.chinese >= 85 && student.math >= 85 && student.english >= 85) "excellent"
          else if (student.chinese < 60 || student.math < 60 || student.english < 60) "danger"
          else if (student.averageScore < 70) "warning"
          else ""
        }
        
        val rankClass = index match {
          case 0 => "highlight"
          case 1 => "highlight"
          case 2 => "highlight"
          case _ => ""
        }
        
        writer.println(s"""
                <tr class="$rowClass $rankClass">
                    <td>${index + 1}</td>
                    <td><strong>${student.name}</strong></td>
                    <td>${student.chinese}</td>
                    <td>${student.math}</td>
                    <td>${student.english}</td>
                    <td><strong>${student.totalScore}</strong></td>
                    <td>${student.averageScore.formatted("%.1f")}</td>
                    <td>${student.overallGrade}</td>
                </tr>""")
      }
      
      writer.println("""
            </tbody>
        </table>""")
      
      // 需要关注的学生
      val studentsNeedingAttention = ScoreAnalyzer.findStudentsNeedingAttention(scores)
      if (studentsNeedingAttention.nonEmpty) {
        writer.println("""
            <h2 style="color: #e74c3c;">⚠️ 需要特别关注的学生</h2>
            <div style="background: #f8d7da; padding: 15px; border-radius: 5px; margin: 20px 0;">""")
        
        studentsNeedingAttention.foreach { case (student, subjects) =>
          writer.println(s"""
                <div style="margin: 10px 0;">
                    <strong>${student.name}</strong>:${subjects.mkString("")}不及格
                    (语文${student.chinese}分,数学${student.math}分,英语${student.english}分)
                </div>""")
        }
        
        writer.println("</div>")
      }
      
      // 报告尾部
      writer.println(s"""
        <div class="footer">
            报告生成系统 v1.0 &copy; ${LocalDateTime.now().getYear} 成绩分析系统
        </div>
    </div>
</body>
</html>""")
      
    } finally {
      writer.close()
    }
  }
}

2.5 主程序入口

package ex_score

import scala.io.Source
import java.io.File

object ScoreAnalysisMain {
  
  def main(args: Array[String]): Unit = {
    println("=== 学生成绩分析系统 ===")
    println()
    
    // 默认文件路径
    val inputFile = if (args.length > 0) args(0) else "score.txt"
    val outputTextFile = "成绩分析报告.txt"
    val outputHtmlFile = "成绩分析报告.html"
    
    // 检查文件是否存在
    if (!new File(inputFile).exists()) {
      println(s"错误:文件 '$inputFile' 不存在")
      println("请确保 score.txt 文件包含以下格式的内容:")
      println("姓名:语文,数学,英语")
      println("张伟:87,92,88")
      println("李娜:90,85,95")
      println("王强:78,90,82")
      return
    }
    
    try {
      // 1. 读取和解析成绩
      println(s"正在读取文件: $inputFile")
      println("-" * 40)
      
      val scores = ScoreParser.readAndParseScores(inputFile).get
      println(s"成功读取 ${scores.length} 名学生成绩")
      
      // 2. 数据验证
      val validationErrors = ScoreParser.validateScores(scores)
      if (validationErrors.nonEmpty) {
        println("警告:发现数据异常:")
        validationErrors.foreach(println)
        println()
      }
      
      // 3. 生成分析报告
      println("正在生成分析报告...")
      
      // 文本报告
      ScoreReportGenerator.generateTextReport(scores, outputTextFile)
      println(s"✓ 文本报告已生成: $outputTextFile")
      
      // HTML报告
      ScoreReportGenerator.generateHtmlReport(scores, outputHtmlFile)
      println(s"✓ HTML报告已生成: $outputHtmlFile")
      
      // 4. 在控制台显示关键信息
      println()
      println("=== 关键统计数据 ===")
      
      val stats = ScoreAnalyzer.calculateClassStatistics(scores)
      
      println("各科平均分:")
      stats.subjectAverages.foreach { case (subject, avg) =>
        println(f"  $subject%-4s: ${avg}%.2f 分")
      }
      
      println(s"\n班级人数: ${stats.totalStudents}")
      
      println("\n等级分布:")
      stats.gradeDistribution.toList.sortBy(_._1).foreach { case (grade, count) =>
        println(f"  $grade 级: $count 人 (${count * 100.0 / stats.totalStudents}%.1f%%)")
      }
      
      println("\n前三名学生:")
      stats.topStudents.zipWithIndex.foreach { case (student, index) =>
        val medals = List("🥇", "🥈", "🥉")
        println(s"  ${medals(index)} ${student.name} - 总分: ${student.totalScore} (平均分: ${student.averageScore.formatted("%.1f")})")
      }
      
      // 5. 查找需要特别关注的学生
      val attentionStudents = ScoreAnalyzer.findStudentsNeedingAttention(scores)
      if (attentionStudents.nonEmpty) {
        println("\n⚠️  需要关注的学生(有不及格科目):")
        attentionStudents.foreach { case (student, subjects) =>
          println(s"  ${student.name}: ${subjects.mkString("、")}不及格")
        }
      }
      
      println()
      println("-" * 40)
      println("分析完成!")
      
    } catch {
      case e: Exception =>
        println(s"错误: ${e.getMessage}")
        e.printStackTrace()
    }
  }
}

3. 扩展功能:成绩录入与修改

package ex_score

import java.io.{PrintWriter, FileWriter, File}
import scala.io.Source

object ScoreManager {
  
  // 添加新成绩
  def addScore(filePath: String, studentScore: StudentScore): Unit = {
    val writer = new FileWriter(filePath, true)  // true 表示追加模式
    try {
      writer.write(s"\n${studentScore.name}${studentScore.chinese}${studentScore.math}${studentScore.english}")
    } finally {
      writer.close()
    }
  }
  
  // 更新成绩
  def updateScore(filePath: String, name: String, newScore: StudentScore): Boolean = {
    val source = Source.fromFile(filePath, "UTF-8")
    val lines = try {
      source.getLines().toList
    } finally {
      source.close()
    }
    
    if (lines.isEmpty) return false
    
    // 更新匹配的行
    val updatedLines = lines.map { line =>
      if (line.startsWith(name + ":")) {
        s"${newScore.name}${newScore.chinese}${newScore.math}${newScore.english}"
      } else {
        line
      }
    }
    
    // 写回文件
    val writer = new PrintWriter(new File(filePath), "UTF-8")
    try {
      updatedLines.foreach(writer.println)
      true
    } finally {
      writer.close()
    }
  }
  
  // 删除成绩
  def deleteScore(filePath: String, name: String): Boolean = {
    val source = Source.fromFile(filePath, "UTF-8")
    val lines = try {
      source.getLines().toList
    } finally {
      source.close()
    }
    
    if (lines.isEmpty) return false
    
    val filteredLines = lines.filterNot(_.startsWith(name + ":"))
    
    // 如果删除了数据,更新文件
    if (filteredLines.length < lines.length) {
      val writer = new PrintWriter(new File(filePath), "UTF-8")
      try {
        filteredLines.foreach(writer.println)
        true
      } finally {
        writer.close()
      }
    } else {
      false
    }
  }
  
  // 批量导入成绩
  def importScores(filePath: String, newScores: List[StudentScore]): Unit = {
    val writer = new FileWriter(filePath, true)
    try {
      newScores.foreach { score =>
        writer.write(s"\n${score.name}${score.chinese}${score.math}${score.english}")
      }
    } finally {
      writer.close()
    }
  }
}

4. 使用示例

创建 score.txt 文件:

姓名:语文,数学,英语
张伟:87,92,88
李娜:90,85,95
王强:78,90,82
赵丽:65,72,68
刘明:95,88,92
陈华:82,76,85

运行程序:

// 方式1:直接运行主程序
ScoreAnalysisMain.main(Array())

// 方式2:自定义文件路径
ScoreAnalysisMain.main(Array("D:/成绩数据/期末成绩.txt"))

// 方式3:在命令行运行
// scala ex_score.ScoreAnalysisMain score.txt

5. 功能特点总结

  1. 完整的成绩分析:总分、平均分、排名、等级
  2. 数据验证:检查成绩范围,确保数据有效性
  3. 多种报告格式:文本报告和HTML可视化报告
  4. 异常处理:使用 Try/Success/Failure 处理可能的错误
  5. 资源管理:自动关闭文件资源
  6. 扩展性强:易于添加新的分析功能
  7. 用户友好:清晰的输出和错误提示
  8. 支持中文:正确处理中文标点和编码