2024-2025-1 20241305 《计算机基础与程序设计》第十四周学习总结
作业信息
这个作业属于哪个课程 | 2024-2025-1-计算机基础与程序设计(https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP)) |
---|---|
这个作业要求在哪里 | 2024-2025-1计算机基础与程序设计第十四周作业 |
这个作业的目标 | 《C语言程序设计》第13-14章并完成云班课测试 |
作业正文 | 本博客链接 |
教材学习内容总结
以下是对《C语言程序设计》第十三章文件操作内容的总结:
13.1二进制文件和文本文件
- 文本文件:
- 文本文件以字符形式存储数据,每个字符对应一个ASCII码值。
- 例如,整数1234在文本文件中存储为字符'1'、'2'、'3'、'4',分别对应ASCII码值49、50、51、52。
- 优点是可读性强,缺点是存储数字等数据时占用空间可能较大。
- 二进制文件:
- 二进制文件以数据在内存中的存储形式直接存储。
- 例如,整数1234在二进制文件中以二进制形式存储(00000100 11010010)。
- 优点是存储效率高,缺点是可读性差。
13.2文件的打开和关闭
- 打开文件:
- 使用
fopen
函数打开文件,函数原型为FILE * fopen(const char * filename, const char * mode);
filename
是文件名,mode
是打开文件的模式,如"r"
(只读)、"w"
(只写,若文件存在则覆盖,不存在则创建)、"a"
(追加,在文件末尾添加数据)、"rb"
(二进制只读)等。- 例如:
- 使用
FILE *fp;
fp = fopen("test.txt", "r");
if(fp == NULL) {
printf("文件打开失败");
return -1;
}
- 关闭文件:
- 使用
fclose
函数关闭文件,函数原型为int fclose(FILE * stream);
- 例如:
- 使用
fclose(fp);
13.3按字符读写文件
- 读字符:
- 使用
fgetc
函数从文件中读取一个字符,函数原型为int fgetc(FILE * stream);
- 例如:
- 使用
FILE *fp;
fp = fopen("test.txt", "r");
int ch;
ch = fgetc(fp);
while(ch!= EOF) {
putchar(ch);
ch = fgetc(fp);
}
fclose(fp);
- 写字符:
- 使用
fputc
函数向文件中写入一个字符,函数原型为int fputc(int c, FILE * stream);
- 例如:
- 使用
FILE *fp;
fp = fopen("output.txt", "w");
char ch = 'A';
fputc(ch, fp);
fclose(fp);
13.4按格式读写文件
- 读数据:
- 使用
fscanf
函数从文件中按格式读取数据,函数原型为int fscanf(FILE * stream, const char * format,...);
- 例如:
- 使用
FILE *fp;
int num;
fp = fopen("data.txt", "r");
fscanf(fp, "%d", &num);
printf("读取的数字为:%d", num);
fclose(fp);
- 写数据:
- 使用
fprintf
函数向文件中按格式写入数据,函数原型为int fprintf(FILE * stream, const char * format,...);
- 例如:
- 使用
FILE *fp;
int num = 10;
fp = fopen("data.txt", "w");
fprintf(fp, "%d", num);
fclose(fp);
13.5按数据块读写文件
- 读数据块:
- 使用
fread
函数从文件中读取数据块,函数原型为size_t fread(void * ptr, size_t size, size_t count, FILE * stream);
- 例如:
- 使用
FILE *fp;
int buffer[10];
fp = fopen("data.bin", "rb");
fread(buffer, sizeof(int), 10, fp);
fclose(fp);
- 写数据块:
- 使用
fwrite
函数向文件中写入数据块,函数原型为size_t fwrite(const void * ptr, size_t size, size_t count, FILE * stream);
- 例如:
- 使用
FILE *fp;
int data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
fp = fopen("data.bin", "wb");
fwrite(data, sizeof(int), 10, fp);
fclose(fp);
13.6.1文件的随机读写
- 文件定位:
- 使用
fseek
函数来移动文件指针,函数原型为int fseek(FILE * stream, long int offset, int whence);
offset
是偏移量,whence
有SEEK_SET
(文件开头)、SEEK_CUR
(当前位置)、SEEK_END
(文件末尾)。- 例如:
- 使用
FILE *fp;
fp = fopen("test.txt", "r+");
fseek(fp, 5L, SEEK_SET);
char ch = fgetc(fp);
fclose(fp);
- 获取当前位置:
- 使用
ftell
函数获取文件指针当前位置,函数原型为long int ftell(FILE * stream);
- 例如:
- 使用
FILE *fp;
long int pos;
fp = fopen("test.txt", "r");
pos = ftell(fp);
fclose(fp);
- 重置文件指针:
- 使用
rewind
函数将文件指针移到文件开头,函数原型为void rewind(FILE * stream);
- 例如:
- 使用
FILE *fp;
fp = fopen("test.txt", "r+");
rewind(fp);
fclose(fp);
13.6.2标准输入/输出重定向
- 输入重定向:
- 在命令行中使用
<
符号来实现输入重定向,例如myprog < input.txt
,程序myprog
的输入将来自input.txt
文件。
- 在命令行中使用
- 输出重定向:
- 在命令行中使用
>
符号来实现输出重定向,例如myprog > output.txt
,程序myprog
的输出将写入output.txt
文件。
- 在命令行中使用
通过对文件操作的这些功能的掌握,可以方便地实现对数据的持久化存储和读取,满足各种应用场景下的数据处理需求。
以下是对《C语言程序设计》第十四章简单的游戏设计内容的总结:
14.1动画的基本原理
-
原理
- 动画的实现基于视觉暂留现象,通过快速连续地显示一系列略有不同的静态图像,给人以动态的视觉效果。在程序中,通常是在短时间内连续地更新显示内容来模拟动画。
- 关键技术包括图形的绘制、擦除和重绘,以及对时间间隔的控制。
-
示例代码思路(简单的图形移动)
- 假设在一个简单的控制台环境下,通过循环来移动一个图形(例如字符)。
#include <stdio.h>
#include <windows.h> // 用于控制控制台的函数
int main() {
int x = 0;
while (1) {
system("cls"); // 清屏,用于擦除之前的图形
for (int i = 0; i < x; i++) {
printf(" ");
}
printf("*"); // 绘制图形(这里用*表示)
Sleep(100); // 暂停一段时间,模拟帧间隔
x++;
if (x > 80) {
x = 0;
}
}
return 0;
}
- 上述代码通过不断清屏、重新绘制图形在不同位置来模拟图形的移动,`Sleep`函数用于控制每次移动的时间间隔。
14.2迷宫游戏
-
游戏设计要点
- 地图设计:用二维数组来表示迷宫地图,例如0表示通路,1表示墙壁。
- 角色移动:通过键盘输入来控制角色在迷宫中的移动方向,每次移动需要判断新位置是否是通路。
- 碰撞检测:判断角色是否碰到墙壁(即移动到值为1的位置)。
- 目标设定:设定出口位置,当角色到达出口时,游戏结束。
-
示例代码思路
#include <stdio.h>
#include <conio.h> // 用于获取键盘输入
#define ROWS 10
#define COLS 10
int maze[ROWS][COLS] = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 1, 1, 1, 0, 1},
{1, 0, 1, 0, 0, 0, 0, 1, 0, 1},
{1, 0, 1, 0, 1, 1, 0, 1, 0, 1},
{1, 0, 0, 0, 1, 1, 0, 1, 0, 1},
{1, 1, 1, 0, 1, 1, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 1, 1, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
int playerX = 1;
int playerY = 1;
void drawMaze() {
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (i == playerY && j == playerX) {
printf("P"); // 表示玩家
} else if (maze[i][j] == 1) {
printf("#"); // 表示墙壁
} else {
printf(" ");
}
}
printf("\n");
}
}
void movePlayer(char direction) {
int newX = playerX;
int newY = playerY;
switch (direction) {
case 'w':
newY--;
break;
case 's':
newY++;
break;
case 'a':
newX--;
break;
case 'b':
newX++;
break;
}
if (maze[newY][newX] == 0) {
playerX = newX;
playerY = newY;
}
}
int main() {
char input;
do {
system("cls");
drawMaze();
input = getch();
movePlayer(input);
} while (maze[playerY][playerX]!= 1 && (playerX!= 8 || playerY!= 8));
printf("游戏结束\n");
return 0;
}
- 这段代码定义了一个简单的迷宫,用`P`表示玩家,`#`表示墙壁,通过`getch`函数获取键盘输入来控制玩家的移动,每次移动时判断是否为可行路径。
14.3 Flappy bird游戏
-
游戏设计要点
- 小鸟的运动:小鸟有一个垂直方向的速度,在每一帧中根据重力加速度更新其垂直位置。
- 管道的生成与移动:定时生成管道对,并使它们从右向左移动,管道之间的间隙随机。
- 碰撞检测:检测小鸟是否与管道或屏幕上下边界发生碰撞。
- 计分机制:小鸟每通过一组管道,分数加1。
-
示例代码思路(简化的核心逻辑)
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
// 小鸟结构体
typedef struct {
int x;
int y;
int velocity;
} Bird;
// 管道结构体
typedef struct {
int x;
int gapY;
} Pipe;
Bird bird;
Pipe pipes[10];
void initGame() {
bird.x = 10;
bird.y = 10;
bird.velocity = 0;
for (int i = 0; i < 10; i++) {
pipes[i].x = 50 + 30 * i;
pipes[i].gapY = (rand() % 10) + 5;
}
}
void drawBird() {
printf("O\n");
}
void drawPipes() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < pipes[i].gapY; j++) {
printf(" ");
}
printf("||");
for (int j = pipes[i].gapY + 3; j < 20; j++) {
printf(" ");
}
printf("||\n");
}
}
void updateBird() {
bird.velocity += 1; // 模拟重力
bird.y += bird.velocity;
}
void updatePipes() {
for (int i = 0; i < 10; i++) {
pipes[i].x -= 1;
if (pipes[i].x < -5) {
pipes[i].x = 50 + 30 * (rand() % 10);
pipes[i].gapY = (rand() % 10) + 5;
}
}
}
int checkCollision() {
// 检查小鸟与管道的碰撞
for (int i = 0; i < 10; i++) {
if (bird.x + 1 >= pipes[i].x && bird.x - 1 <= pipes[i].x + 2 &&
(bird.y <= pipes[i].gapY || bird.y >= pipes[i].gapY + 3)) {
return 1;
}
}
// 检查小鸟与边界的碰撞
if (bird.y <= 0 || bird.y >= 20) {
return 1;
}
return 0;
}
int main() {
initGame();
while (1) {
system("cls");
drawPipes();
drawBird();
updateBird();
updatePipes();
if (checkCollision()) {
printf("游戏结束\n");
break;
}
Sleep(100);
}
return 0;
}
- 上述代码定义了小鸟和管道的结构体,实现了游戏的初始化、绘制小鸟和管道、更新小鸟和管道位置以及碰撞检测等功能。通过循环不断更新游戏状态来模拟Flappy bird游戏的运行。
这些游戏设计示例展示了C语言在简单游戏开发中的应用,通过对图形绘制、用户输入处理、逻辑更新和碰撞检测等方面的编程实现了有趣的游戏效果。
教材学习中的问题和解决过程(先问 AI)
问题一:提供一些在C语言中处理文件读写错误的示例代码
解决:以下是一些在 C 语言中处理文件读写错误的示例代码,涵盖了文件打开、读取、写入和关闭时的错误处理:
一、文件打开错误处理
#include <stdio.h>
#include <stdlib.h> // 用于 exit 函数
int main() {
FILE *fp;
fp = fopen("example.txt", "r");
if (fp == NULL) {
perror("Error opening file"); // 输出错误信息,包括系统错误描述
exit(EXIT_FAILURE); // 终止程序,并返回错误状态
}
// 文件操作代码
fclose(fp);
return 0;
}
代码解释:
fopen("example.txt", "r")
:尝试以只读模式打开文件example.txt
。if (fp == NULL)
:检查文件指针是否为NULL
,如果为NULL
表示文件打开失败。perror("Error opening file")
:输出自定义错误信息"Error opening file"
并附加系统错误描述。exit(EXIT_FAILURE)
:终止程序并返回错误状态。
二、文件读取错误处理
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
char buffer[100];
fp = fopen("example.txt", "r");
if (fp == NULL) {
perror("Error opening file");
exit(EXIT_FAILURE);
}
if (fgets(buffer, sizeof(buffer), fp) == NULL) {
if (ferror(fp)) { // 检查是否发生读取错误
perror("Error reading file");
fclose(fp);
exit(EXIT_FAILURE);
} else if (feof(fp)) { // 检查是否到达文件末尾
printf("End of file reached.\n");
}
}
// 成功读取数据,可进行后续处理
printf("Read data: %s", buffer);
fclose(fp);
return 0;
}
代码解释:
fgets(buffer, sizeof(buffer), fp)
:尝试从文件中读取数据到buffer
中。if (fgets(buffer, sizeof(buffer), fp) == NULL)
:如果fgets
失败,检查是因为读取错误(ferror(fp)
)还是到达文件末尾(feof(fp)
)。perror("Error reading file")
:输出读取错误信息。
三、文件写入错误处理
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
fp = fopen("example.txt", "w");
if (fp == NULL) {
perror("Error opening file");
exit(EXIT_FAILURE);
}
if (fprintf(fp, "Hello, World!") < 0) { // 检查 fprintf 是否成功
perror("Error writing to file");
fclose(fp);
exit(EXIT_FAILURE);
}
fflush(fp); // 刷新文件缓冲区
if (ferror(fp)) { // 检查是否发生写入错误
perror("Error writing to file");
fclose(fp);
exit(EXIT_FAILURE);
}
fclose(fp);
return 0;
}
代码解释:
fprintf(fp, "Hello, World!")
:尝试将字符串"Hello, World!"
写入文件。if (fprintf(fp, "Hello, World!") < 0)
:检查fprintf
是否成功。fflush(fp)
:刷新文件缓冲区,确保数据被写入文件。if (ferror(fp))
:检查是否发生写入错误。
四、文件关闭错误处理
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
fp = fopen("example.txt", "w");
if (fp == NULL) {
perror("Error opening file");
exit(EXIT_FAILURE);
}
// 文件操作代码
if (fclose(fp)!= 0) { // 检查文件是否成功关闭
perror("Error closing file");
exit(EXIT_FAILURE);
}
return 0;
}
代码解释:
if (fclose(fp)!= 0)
:检查fclose
函数的返回值,如果不为 0 表示文件关闭失败。
这些示例代码展示了如何在 C 语言中对文件操作的各个环节进行错误处理,以确保程序的健壮性。在实际应用中,根据不同的错误情况,可以采取不同的错误处理策略,例如重试操作、记录错误日志、向用户报告错误等。同时,结合文件操作的不同模式和函数,可以根据具体需求调整错误处理代码。
基于AI的学习
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第十四周 | 500/4900 | 2/21 | 15/245 |
计划学习时间:15h
实际学习时间:15h