VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > c#编程 >
  • 控制台高级交互——用C#开发菜单驱动式应用程序

第一部分:C#基础入门
实例10:控制台高级交互——菜单驱动式应用程序
实例介绍
菜单驱动式应用是控制台程序的经典形态,广泛用于管理系统、工具类程序等场景。用户通过选择数字/字母来触发功能,核心是交互流程的流畅性和输入的鲁棒性(防止非法输入崩溃)。本实例通过实现一个学生信息管理系统的控制台菜单,掌握多级菜单设计、输入验证、循环控制、状态保存等核心技巧,让控制台程序既实用又友好。
需求分析
1.多级菜单结构:主菜单包含「学生信息管理」「成绩管理」「退出」,子菜单(如学生管理)包含「添加学生」「查看学生」「返回主菜单」;
2.输入验证:仅允许合法数字选择(如主菜单只能输入1-3),非法输入时提vb.net教程C#教程python教程SQL教程access 2010教程
示并重新输入;
3.菜单循环:用户操作后不直接退出,返回当前菜单继续操作;
4.数据暂存:用列表保存添加的学生信息,支持查看;
5.友好提示:操作成功/失败时给出清晰反馈,错误输入时引导用户;
6.安全退出:提供明确的退出选项,避免程序强制终止。
代码实现
csharp

	using System;
	using System.Collections.Generic;
	
	namespace MenuDrivenAppDemo
	{
	// 学生信息类:存储基础数据
	public class Student
	{
	public int Id { get; set; }
	public string Name { get; set; }
	public int Age { get; set; }
	
	public override string ToString()
	{
	return $"ID:{Id} | 姓名:{Name} | 年龄:{Age}";
	}
	}
	
	// 静态数据存储类:全局共享学生信息
	public static class DataStore
	{
	public static List<Student> Students = new List<Student>();
	private static int _nextStudentId = 1; // 自动生成ID
	
	// 获取下一个学生ID(自增)
	public static int GetNextStudentId() => _nextStudentId++;
	}
	
	// 菜单驱动主程序
	class Program
	{
	static void Main(string[] args)
	{
	ShowMainMenu(); // 启动主菜单
	}
	
	#region 主菜单逻辑
	private static void ShowMainMenu()
	{
	while (true) // 菜单循环:直到用户选择退出
	{
	Console.Clear(); // 清空控制台,提升体验
	Console.WriteLine("=== 学生信息管理系统 ===");
	Console.WriteLine("1. 学生信息管理");
	Console.WriteLine("2. 成绩管理(待实现)");
	Console.WriteLine("3. 退出程序");
	Console.Write("请输入选择(1-3):");
	
	// 获取合法输入(仅允许1-3)
	int choice = GetValidIntegerInput(1, 3);
	
	switch (choice)
	{
	case 1:
	ShowStudentSubMenu(); // 进入学生管理子菜单
	break;
	case 2:
	ShowNotImplementedMessage(); // 提示功能未实现
	break;
	case 3:
	Console.WriteLine("感谢使用,再见!");
	Console.ReadKey();
	return; // 退出程序
	}
	}
	}
	#endregion
	
	#region 学生管理子菜单逻辑
	private static void ShowStudentSubMenu()
	{
	while (true)
	{
	Console.Clear();
	Console.WriteLine("=== 学生信息管理子菜单 ===");
	Console.WriteLine("1. 添加学生");
	Console.WriteLine("2. 查看所有学生");
	Console.WriteLine("3. 返回主菜单");
	Console.Write("请输入选择(1-3):");
	
	int choice = GetValidIntegerInput(1, 3);
	
	switch (choice)
	{
	case 1:
	AddStudent();
	break;
	case 2:
	ViewAllStudents();
	break;
	case 3:
	return; // 返回主菜单
	}
	}
	}
	#endregion
	
	#region 功能实现
	private static void AddStudent()
	{
	Console.Clear();
	Console.WriteLine("=== 添加学生 ===");
	
	// 获取学生姓名(非空验证)
	string name;
	while (true)
	{
	Console.Write("请输入学生姓名:");
	name = Console.ReadLine()?.Trim() ?? "";
	if (!string.IsNullOrEmpty(name)) break;
	Console.WriteLine("姓名不能为空,请重新输入!");
	}
	
	// 获取学生年龄(1-100)
	Console.Write("请输入学生年龄:");
	int age = GetValidIntegerInput(1, 100);
	
	// 生成ID并添加到列表
	int studentId = DataStore.GetNextStudentId();
	DataStore.Students.Add(new Student
	{
	Id = studentId,
	Name = name,
	Age = age
	});
	
	Console.WriteLine($"添加成功!学生ID:{studentId}");
	WaitForKeyPress(); // 等待用户按键返回子菜单
	}
	
	private static void ViewAllStudents()
	{
	Console.Clear();
	Console.WriteLine("=== 所有学生信息 ===");
	
	if (DataStore.Students.Count == 0)
	{
	Console.WriteLine("暂无学生信息!");
	}
	else
	{
	foreach (var student in DataStore.Students)
	{
	Console.WriteLine(student.ToString());
	}
	}
	
	WaitForKeyPress();
	}
	#endregion
	
	#region 工具函数(复用逻辑)
	/// <summary>
	/// 获取合法的整数输入(范围验证)
	/// </summary>
	/// <param name="min">最小允许值</param>
	/// <param name="max">最大允许值</param>
	/// <returns>合法的整数</returns>
	private static int GetValidIntegerInput(int min, int max)
	{
	int input;
	while (true)
	{
	string inputStr = Console.ReadLine()?.Trim() ?? "";
	if (int.TryParse(inputStr, out input) && input >= min && input <= max)
	{
	break; // 输入合法,退出循环
	}
	Console.Write($"输入无效,请输入{min}-{max}之间的数字:");
	}
	return input;
	}
	
	/// <summary>
	/// 等待用户按键(用于操作后暂停)
	/// </summary>
	private static void WaitForKeyPress()
	{
	Console.WriteLine("
按任意键继续...");
	Console.ReadKey(true); // true:不显示用户按下的键
	}
	
	/// <summary>
	/// 显示功能未实现提示
	/// </summary>
	private static void ShowNotImplementedMessage()
	{
	Console.WriteLine("该功能尚未实现,敬请期待!");
	WaitForKeyPress();
	}
	#endregion
	}
	}

逐行讲解

  1. 数据存储类(DataStore)
    csharp
	public static class DataStore
	{
	public static List<Student> Students = new List<Student>();
	private static int _nextStudentId =1;
	public static int GetNextStudentId() => _nextStudentId++;
	}

静态类:全局共享数据,无需实例化即可访问;
Students列表:存储所有添加的学生信息;
_nextStudentId:自动生成唯一ID(自增),避免手动输入冲突;
GetNextStudentId:返回当前ID并自增,简化ID管理。
2. 输入验证函数(GetValidIntegerInput)
csharp

	private static int GetValidIntegerInput(int min, int max)
	{
	int input;
	while(true)
	{
	string inputStr = Console.ReadLine()?.Trim() ?? "";
	if(int.TryParse(inputStr, out input) && input >= min && input <= max) break;
	Console.Write($"输入无效,请输入{min}-{max}之间的数字:");
	}
	return input;
	}

循环验证:直到用户输入合法数字才退出;
int.TryParse:安全解析字符串为整数,避免输入非数字时抛出异常;
范围检查:确保输入在指定范围内(如主菜单只能1-3);
空值处理:用?? ""将null转为空字符串,防止Trim()调用时的空引用。
3. 主菜单循环(ShowMainMenu)
csharp

	private static void ShowMainMenu()
	{
	while(true)
	{
	Console.Clear(); // 清空控制台,保持界面整洁
	// ...显示菜单...
	int choice = GetValidIntegerInput(1,3);
	switch(choice)
	{
	case1: ShowStudentSubMenu(); break;
	case3: return; // 退出程序
	}
	}
	}

while(true):无限循环,直到用户选择退出;
Console.Clear():每次显示菜单前清空屏幕,提升用户体验;
switch-case:根据选择执行对应逻辑,子菜单通过函数调用实现多级结构。
4. 子菜单逻辑(ShowStudentSubMenu)
csharp

	private static void ShowStudentSubMenu()
	{
	while(true)
	{
	// ...显示子菜单...
	int choice = GetValidIntegerInput(1,3);
	if(choice ==3) return; // 返回主菜单
	// ...处理其他选择...
	}
	}

返回机制:选择“返回主菜单”时用return退出当前函数,回到主菜单循环;
复用工具函数:输入验证、等待按键等逻辑复用,减少重复代码。
5. 添加学生功能(AddStudent)
csharp

	private static void AddStudent()
	{
	// ...姓名非空验证...
	while(true)
	{
	name = Console.ReadLine()?.Trim() ?? "";
	if(!string.IsNullOrEmpty(name)) break;
	}
	// ...年龄验证...
	DataStore.Students.Add(new Student{Id=studentId, Name=name, Age=age});
	}

姓名非空验证:用循环强制用户输入非空姓名;
年龄范围验证:复用GetValidIntegerInput确保年龄在1-100之间;
自动ID:调用DataStore.GetNextStudentId生成唯一ID,无需用户干预。
基础知识拓展

  1. 控制台交互核心技巧
方法/属性 作用 示例
Console.Clear() 清空控制台屏幕 Console.Clear()
Console.ReadKey(bool intercept) 获取用户按键,intercept=true时不显示按键 Console.ReadKey(true)
Console.ForegroundColor 设置输出文字颜色 Console.ForegroundColor = ConsoleColor.Green
int.TryParse(string s, out int result) 安全解析字符串为整数,返回是否成功 int.TryParse(inputStr, out input)
  1. 循环控制的选择
    while(true):适合无限循环(如菜单),需手动用break/return退出;
    do-while:适合至少执行一次的场景(如输入验证);
    for:适合固定次数的循环(如遍历列表)。
  2. 多级菜单的实现方式
    函数嵌套:如主菜单调用子菜单函数,子菜单用return返回主菜单;
    状态机:用枚举表示当前菜单状态(如MenuState.Main/MenuState.StudentSub),通过switch-case处理;
    配置化菜单:用字典存储菜单选项(如Dictionary<int, Action>),动态添加菜单功能。
  3. 代码复用的重要性
    工具函数:将输入验证、等待按键等通用逻辑封装为函数,减少重复代码;
    静态类:如DataStore,集中管理共享数据,避免全局变量的混乱;
    面向对象:用Student类封装数据,提升代码可读性和可维护性。
    扩展思考
    1.菜单美化:添加颜色(如标题用绿色,错误提示用红色);
    2.数据持久化:将学生信息保存到文件(如JSON/CSV),下次启动时加载;
    3.快捷键支持:如按ESC键直接退出程序;
    4.错误处理:用try-catch捕获异常(如文件读写错误);
    5.菜单配置化:用List存储菜单选项,动态生成菜单;
    6.分页功能:当学生数量过多时,实现分页查看。
    总结
    菜单驱动式应用的核心是用户体验和逻辑清晰:
    输入验证是鲁棒性的关键,避免非法输入导致程序崩溃;
    循环控制是菜单流程的基础,确保用户操作后不退出;
    代码复用提升开发效率,减少维护成本;
    多级菜单通过函数嵌套实现,结构清晰易扩展。
    掌握这些技巧,你可以轻松构建各种控制台管理系统,为后续学习桌面应用或Web开发打下坚实基础。

本站原创,转载请注明出处:https://www.xin3721.com/ArticlecSharp/c49401.html


相关教程