4.10.1 建立播放列表

数据字典

名称 数据类型 说明
MAX_LENGTH 符号常量 用于定义数组长度,表示列表最大长度
MAX_FILE_LENGTH 符号常量 用于定义数组长度,表示文件名最大长度
GET_NAME 符号常量 用于scanf()函数输入文件名,说明输入字符串的长度,值为 %<MAX_FILE_LENGTH>s
*p_list 整型指针数组 用于指定播放列表的顺序
f_list 二维字符数组 用于保存播放列表中文件路径与名称,MAX_LENGTH作为第一维长度,MAX_FILE_LENGTH作为第二维长度
i 整型变量 用于遍历播放列表,值域为 0 至 MAX_LENGTH - 1
len 整型变量 用于保存播放列表当前长度,该长度小于 MAX_LENGTH
select_value 整型变量 用于接收键盘输入的菜单选择
exit_switch 字符变量 用于控制程序主操作循环的退出
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define MAX_LENGTH 5 // 定义数组长度,表示列表最大长度
  5. #define MAX_FILE_LENGTH 255 // 定义数组长度,表示文件名最大长度
  6. #define GET_NAME "%255s" // 用于 scanf() 函数输入文件名,说明输入字符串的长度
  7.  
  8. int main()
  9. {
  10. unsigned int i, len;
  11. char *p_list[MAX_LENGTH]; // 定义指针列表
  12. char f_list[MAX_LENGTH][MAX_FILE_LENGTH + 1]; // 定义文件名列表,件名最大长度加 1 是用于存放字符串结束符
  13. unsigned int j; // 用于排序的循环控制变量
  14. char *p_temp; // 用于排序时交换指针列表中的数据
  15.  
  16. for (i = 0; i < MAX_LENGTH; i++) // 用循环对指针列表和文件名列表初始化
  17. {
  18. p_list[i] = NULL; // 将指针列表指向NULL
  19. f_list[i][0] = 0; // 将字符串列表首位置 0
  20. }
  21.  
  22. int select_value; // 用于 接收键盘输入的菜单选择
  23. char exit_switch = 1; // 用于 控制程序主操作循环的退出
  24. len = 0; // 初始化列表长度
  25.  
  26. do
  27. {
  28. puts("请选择操作命令:");
  29. puts("(1)添加新文件");
  30. puts("(2)删除列表中的文件");
  31. puts("(3)打印播放列表");
  32. puts("(4)退出程序");
  33. puts("(5)按文件名排序");
  34.  
  35. scanf("%1d", &select_value); // 输入菜单选择
  36. getchar(); // 吸收多余的输入字符
  37.  
  38. switch (select_value)
  39. {
  40. case 1: // 添加 文件
  41.  
  42. if (len < MAX_LENGTH)
  43. {
  44. puts("请输入文件名");
  45. for (i = 0; i < MAX_LENGTH; i++)
  46. {
  47. if (!f_list[i][0]) // 二维字符数组行首为 0,则表示是空位
  48. {
  49. while (!scanf(GET_NAME, f_list[i])) // 输入文件名,并判断文件名是否有效
  50. {
  51. puts("请输入正确的文件名");
  52. }
  53. p_list[len++] = f_list[len]; // 将指针列表所对应的单元,指向文件名存放的内存地址
  54. break;
  55. }
  56. }
  57. }
  58. else
  59. {
  60. puts("文件列表已满!");
  61. }
  62.  
  63. break;
  64. case 2: // 删除列表中的文件
  65.  
  66. puts("请输入文件编号:");
  67. scanf("%u", &i);
  68. if (i > 0 && i <= len) // 判断编号是否有效,有效的编码在 1 和 总长度之间
  69. {
  70. *p_list[--i] = NULL; // 通过指针间接引用文件列表,将目标文件名删除
  71. while (i < len - 1) // 循环,从列表中删除的位置到列表结束
  72. {
  73. p_list[i] = p_list[i + 1]; // 将游标所指向的指针列表后的元素向前挪进 1 位
  74. i++;
  75. }
  76. len--; // 列表长度 减 1
  77. }
  78. else
  79. {
  80. puts("您所输入的文件编号不存在!");
  81. }
  82.  
  83. break;
  84. case 3: // 打印播放列表
  85.  
  86. for (i = 0; i < len; i++)
  87. {
  88. printf("%d : %s\n", i + 1, p_list[i]);
  89. }
  90.  
  91. break;
  92. case 5: // 按文件名排序
  93.  
  94. if (len > 1)
  95. {
  96. for (i = 0; i < len - 1; i++)
  97. {
  98. for (j = i + 1; j < 1; j++)
  99. {
  100. if (*p_list[i] > *p_list[j]) // 比较 2 个文件名字符串首个字符大小
  101. {
  102. p_temp = p_list[i];
  103. p_list[i] = p_list[j];
  104. p_list[j] = p_temp;
  105. }
  106. }
  107. }
  108. }
  109.  
  110. break;
  111. default:
  112.  
  113. exit_switch = 0;
  114.  
  115. break;
  116. }
  117.  
  118. } while (exit_switch);
  119.  
  120. return EXIT_SUCCESS;
  121. }

该代码设置了一个主控制循环,由主控循环反复输入控制提示信息,并等待用户的输入。用户可输入指定的数字来执行对应的操作。

  • 输入数字 1,程序提示键入文件名,文件名并不是按列表的顺序存放在字符数组 f_list 中,而是在遍历数组 f_list 寻找行首为 0 的空位。储存成功后,将字符串在内存中的首地址传送给指针列表 p_list,p_list 则是按列表保存每个文件名字符串的地址。
  • 输入数字 2,程序提示输入文件编号,该编号是从 1 开始的,所以在进行删除处理前,要将保存编号的游标 i 自减1。删除文件名字符串,只需要将该字符串行首的元素置0。然后依次将指针列表中游标所指向位置以后的数值复制到前 1 位,再将列表总长度减去 1。这样,可以删除列表中任何位置的字符串。
  • 输入数字 3,程序将顺序打印播放列表,首先用游标从列表头开始遍历,再用指针列表参照游标的数值间接引用文件名列表。
  • 输入数字 4,程序主操作循环退出标记 exit_switch 被置为 0,操作结束后程序跳出主循环,这样就能退出程序。

注意:在 do 循环中,scanf() 函数接收一个数字字符作为用户操作菜单的指令。如果用户输入 非法字符,这些字符将进入下一轮循环,并被 scanf()函数接收作为输入。这是由于标准输入的缓冲区缓冲所造成的,形成真正的死循环。如果在 scanf() 函数后用 getchar() 函数接收这些非法字符,即可避免该问题。

4.10.2 对播放列表排序

用户在使用媒体播放器时,经常会根据自己的喜好对播放列表进行排序。排序的方法有按名称排序、按播放时长排序、按媒体信息排序。各种排序的原理大同小异,所以这里只选择了按名称排序来演示播放列表排序的程序设计方法。

排序只有在列表长度大于 1 时才有意义,所以首先要判断列表长度是否大于 1,然后用双层循环变量 *p_list 数组。比较两个数组元素所指向内存中的内容,如果前面的内容大于后者,则交换 *p_list 数组元素的地址。

具体见上例中的 case 5。

【C语言入门教程】4.10 综合实例 - 媒体播放器的更多相关文章

  1. 智能合约语言 Solidity 教程系列10 - 完全理解函数修改器

    这是Solidity教程系列文章第10篇,带大家完全理解Solidity的函数修改器. Solidity系列完整的文章列表请查看分类-Solidity. 写在前面 Solidity 是以太坊智能合约编 ...

  2. C语言入门教程: 一个简单的实例

    对于学习要保持敬畏! 语言不只是一种工具,还是一种资源,因此,善待它,掌握它!   我们知道,对于未知通常都会充满好奇和畏惧,既想了解它,又害怕神秘面纱隐藏的不确定性.对于一门编程语言同样如此,我将以 ...

  3. 《Ruby语言入门教程v1.0》学习笔记-01

    <Ruby语言入门教程v1.0> 编著:张开川 邮箱:kaichuan_zhang@126.com 想要学习ruby是因为公司的自动化测试使用到了ruby语言,但是公司关于ruby只给了一 ...

  4. C语言入门教程-(5)格式化输入输出

    1.输入和输出 在程序的使用中,我们经常可以看的这么一个场景:用户需要输入数据,经过程序运算,得到结果后输出.在C语言中,输入数据和输出数据都是由库函数完成的,通过语句来输入/输出. 2.格式化输出— ...

  5. 《JavaScript语言入门教程》记录整理:运算符、语法和标准库

    目录 运算符 算数运算符 比较运算符 布尔运算符 二进制位运算符 void和逗号运算符 运算顺序 语法 数据类型的转换 错误处理机制 编程风格 console对象和控制台 标准库 Object对象 属 ...

  6. 《JavaScript语言入门教程》记录整理:面向对象

    目录 面向对象编程 实例对象与 new 命令 this关键字 对象的继承 Object对象的方法 严格模式(strict mode) 本系列基于阮一峰老师的<JavaScrip语言入门教程> ...

  7. 【C语言入门教程】目录/大纲

    第一章 C语言编程基础 1.1 基本程序结构 1.2 函数库 和 链接 1.3 C语言“32个”关键字 第二章 数据类型.运算符和表达式 2.1 数据类型(5种基本数据类型),聚合类型与修饰符 2.2 ...

  8. Go语言入门教程(十)之函数

    Hello 各位小伙伴大家好,我是小栈君,假期一眨眼就过去了.不知道大家玩的是否开心呢? 上次我们讲到了关于Go语言的流程控制,小栈君也希望小伙伴跟着小栈君一步一个脚印的敲一下代码,相互进步.本期我们 ...

  9. 《JavaScript语言入门教程》记录整理:入门和数据类型

    目录 入门篇 js介绍 历史 基本语法 数据类型 概述 null 和 undefined 数值 字符串 对象 函数 数组 本系列基于阮一峰老师的<JavaScrip语言入门教程>或< ...

随机推荐

  1. 加州大学伯克利分校Stat2.2x Probability 概率初步学习笔记: Section 3 The law of averages, and expected values

    Stat2.2x Probability(概率)课程由加州大学伯克利分校(University of California, Berkeley)于2014年在edX平台讲授. PDF笔记下载(Acad ...

  2. 一个关于AdaBoost算法的简单证明

    下载本文PDF格式(Academia.edu) 本文给出了机器学习中AdaBoost算法的一个简单初等证明,需要使用的数学工具为微积分-1. Adaboost is a powerful algori ...

  3. iOS 获得当前经纬度和城市

    1.引入CoreLocation.framework,#import <CoreLocation/CoreLocation.h>,添加委托CLLocationManagerDelegate ...

  4. jquery获取复选框的值

    勾选checkbox,并把勾选的值显示在某个div中 <!DOCTYPE html > <html> <head> <meta charset="U ...

  5. Tomcat 的 ErrorPage 实现原理分析

    使用Tomcat,一定见到过404,500的时候,见到过Tomcat提供的错误页面,例如请求的资源找不到的时候,响应状态码为404,这个时候的错误页面是这样的: 这些错误页面是 如何生成及定位展示的  ...

  6. 【浅谈html5 响应式布局之自动适应屏幕宽度】

    允许网页宽度自动调整 “自适应网页设计”到底是怎么做到的?其实并不难. 首先,在网页代码的头部,加入一行viewport元标签. <meta name=”viewport” content=”w ...

  7. SVN服务器配置说明

    1.前 言 花了72小时,终于把 Subversion 初步掌握了.从一个连“什么是版本控制”都不知道的门外汉,到配置出精确至每目录访问的入门者,中间还卡了一天时间.其中费了许多气力,摸索实验了多次, ...

  8. Laravel教程 七:表单验证 Validation

    Laravel教程 七:表单验证 Validation 此文章为原创文章,未经同意,禁止转载. Laravel Form 终于要更新这个Laravel系列教程的第七篇了,期间去写了一点其他的东西. 就 ...

  9. Jquerymobile随笔

    fixed <div data-role="header" data-position="fixed"> <h1>欢迎访问我的主页< ...

  10. Latex论文写作-Texsdudio 快捷键总结

    Latex论文写作-Texsdudio 快捷键总结  The keyboard shortcuts can be modified at Options -> Shortcuts. The fo ...