作业信息
这个作业属于哪个课程 | 2024-2025-1-计算机基础与程序设计) |
---|---|
这个作业要求在哪里 | <作业要求的链接>https://www.cnblogs.com/rocedu/p/9577842.html#WEEK14 |
这个作业的目标 | <写上具体方面>《C语言程序设计》第13-14章并完成云班课测试 |
作业正文 | https://www.cnblogs.com/tanzitian11/p/18638066 |
教材学习内容总结
文件操作
文件的基本概念
在 C 语言中,文件是存储在外部介质(如磁盘)上的数据集合。
文件可以是文本文件(由字符序列组成,每个字符占一个字节,如.txt文件),也可以是二进制文件(以二进制的形式存储数据,像.dat文件)。
从文件的读写角度看,文件分为输入文件(从文件读取数据,如读取配置文件)和输出文件(向文件写入数据,如记录日志文件)。
文件指针
文件指针是一个指向文件类型(FILE)结构体的指针变量。
FILE结构体在<stdio.h>
头文件中定义,它包含了文件的各种信息,如文件的当前读写位置、缓冲区信息等。
例如,定义一个文件指针FILE *fp
;,通过这个指针可以对文件进行操作。在打开一个文件后,fp
就指向该文件的相关信息结构体。
文件的打开与关闭
打开文件:使用fopen()
函数打开文件,其原型为FILE * fopen(const char *filename, const char *mode);
。
filename是要打开的文件名(包括路径),例如"data.txt"。
mode是打开文件的模式,常见的模式有:
"r"
:以只读方式打开文本文件。如果文件不存在,则打开失败。
"w"
:以只写方式打开文本文件。如果文件存在,则先删除文件内容;如果文件不存在,则创建新文件。
"a"
:以追加方式打开文本文件。如果文件不存在,则创建新文件;写入的数据会添加到文件末尾。
"rb"
、"wb"
、"ab"
:分别是以二进制方式进行读、写、追加操作。
例如,fp = fopen("test.txt","w");
是以只写方式打开test.txt文件。如果打开成功,fp指向该文件,否则fp的值为NULL。
关闭文件:使用fclose()
函数关闭文件,其原型为int fclose(FILE *stream);
。
例如,fclose(fp);
将关闭fp所指向的文件。关闭文件非常重要,它可以确保文件缓冲区中的数据被正确写入磁盘,并且释放文件相关的系统资源。
文件的读写操作
字符读写:
fgetc()
函数用于从文件中读取一个字符,其原型为int fgetc(FILE *stream);。它返回读取到的字符的 ASCII 码值,如果遇到文件末尾或者读取错误,则返回EOF
(EOF是在<stdio.h>中定义的一个常量,通常值为 - 1)。例如,int ch; fp = fopen("text.txt","r"); ch = fgetc(fp);
将从text.txt文件中读取一个字符并存储在ch中。
fputc()
函数用于向文件中写入一个字符,其原型为int fputc(int c, FILE *stream);
。其中c是要写入的字符的 ASCII 码值。例如,fputc('A',fp);
将字符A写入fp所指向的文件中。
字符串读写:
fgets()
函数用于从文件中读取一个字符串,其原型为char * fgets(char *str, int n, FILE *stream);
。str是存储读取字符串的字符数组,n是最多读取的字符个数(包括'\0')。它读取字符直到遇到换行符'\n'、文件末尾或者已经读取了n - 1个字符,然后在读取的字符串末尾添加'\0'。例如,char buf[100]; fp = fopen("text.txt","r"); fgets(buf,100,fp);
将从text.txt文件中读取最多 99 个字符并存入buf数组中。
fputs()
函数用于向文件中写入一个字符串,其原型为int fputs(const char *str, FILE *stream);
。例如,fputs("Hello World",fp);
将把字符串"Hello World"写入fp所指向的文件中。
格式化读写:
fscanf()
函数用于从文件中按照指定格式读取数据,其原型为int fscanf(FILE *stream, const char *format,...);
。它的使用方法类似于scanf()
函数,但是数据来源是文件。例如,int num; fp = fopen("data.txt","r"); fscanf(fp,"%d",&num);
将从data.txt文件中读取一个整数存入num变量中。
fprintf()
函数用于向文件中按照指定格式写入数据,其原型为int fprintf(FILE *stream, const char *format,...);
。它的使用方法类似于printf()
函数,但是输出目标是文件。例如,int score = 90; fp = fopen("result.txt","w"); fprintf(fp,"The score is %d",score);
将把格式化后的字符串写入result.txt文件中。
块读写(二进制文件读写):
fread()
函数用于从二进制文件中读取数据块,其原型为size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
。ptr是存储读取数据的内存地址,size是每个数据单元的大小(字节数),count是要读取的数据单元个数,函数返回实际读取的数据单元个数。例如,读取一个包含 10 个整数的二进制文件:int arr[10]; fp = fopen("binary.dat","rb"); fread(arr, sizeof(int),10,fp);
fwrite()
函数用于向二进制文件中写入数据块,其原型为size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
。例如,将一个整数数组写入二进制文件:int arr[5] = {1,2,3,4,5}; fp = fopen("binary.dat","wb"); fwrite(arr, sizeof(int),5,fp);
文件的定位操作
ftell()
函数用于获取文件指针的当前位置,其原型为long ftell(FILE *stream);
。返回值是相对于文件开头的字节数。例如,long pos = ftell(fp);
可以获取fp所指向文件的当前位置。
fseek()函数用于移动文件指针的位置,其原型为int fseek(FILE *stream, long offset, int whence);
。offset是偏移量,whence指定偏移的起始位置,有三种取值:
SEEK_SET:文件开头,偏移量从文件开头计算。
SEEK_CUR:文件当前位置,偏移量从当前位置计算。
SEEK_END:文件末尾,偏移量从文件末尾计算。例如,fseek(fp, - 10L, SEEK_END);将文件指针从文件末尾向前移动 10 个字节。
rewind()
函数用于将文件指针重新定位到文件开头,其原型为void rewind(FILE *stream);。例如,rewind(fp);将fp所指向的文件指针移回文件开头
简单的游戏设计
C 语言动画基本原理
帧的概念:动画的基本原理是快速连续地显示一系列略有不同的图像(帧),当这些帧以足够快的速度切换时,在人眼看来就形成了连续的动画效果。在 C 语言中,这可以通过在控制台或图形界面中不断更新显示内容来实现。例如,在控制台中模拟一个简单的小球移动动画,通过不断地改变小球的位置并重新绘制来产生动画效果。
循环更新显示:通常使用循环结构(如while循环或for循环)来不断更新每一帧的内容。在每次循环中,进行图形的绘制或位置的调整,然后通过适当的延时和清屏操作,使新的画面显示出来,替换旧的画面。
清屏操作
在不同操作系统下的方法:
Windows 系统:在 C 语言中,可以通过调用系统命令system("cls")
来清屏。这是利用了system函数执行操作系统命令的功能,cls是 Windows 下的清屏命令。例如:
#include <stdio.h>
#include <stdlib.h>
int main()
{printf("这是在清屏前的内容。\n");system("cls");printf("这是清屏后的内容。\n");return 0;
}
Linux 和 Unix 系统:对应的清屏命令是system("clear")
,其原理和使用方式与 Windows 下的system("cls")类似,只是命令不同,因为不同操作系统的终端命令不同。
延时操作
使用Sleep函数(Windows)或usleep函数(Linux):
Windows 系统:在 Windows 环境下,可以使用Sleep函数来实现延时。Sleep函数包含在<windows.h>头文件中,它的参数是延时的毫秒数。例如:
#include <stdio.h>
#include <windows.h>
int main()
{printf("开始延时。\n");Sleep(3000); //延时3秒printf("延时结束。\n");return 0;
}
Linux 和 Unix 系统:在 Linux 和 Unix 系统中,可以使用usleep函数来实现微秒级别的延时。它包含在<unistd.h>头文件中。例如,要实现 1 秒(1000000 微秒)的延时,可以这样写:
#include <stdio.h>
#include <unistd.h>
int main()
{printf("开始延时。\n");usleep(1000000);printf("延时结束。\n");return 0;
}
检测用户键盘输入
使用getch函数(非标准函数)或getchar函数(标准函数):
getch函数:getch函数在<conio.h>头文件中(这是一个非标准的头文件,在一些编译器中可能需要特殊配置才能使用),它可以直接从键盘获取一个字符,并且不需要用户按下回车键。例如:
#include <stdio.h>
#include <conio.h>
int main()
{char ch;printf("请按一个键:");ch = getch();printf("你按下的键是:%c\n", ch);return 0;
}
getchar函数:getchar函数是 C 语言标准库函数,包含在<stdio.h>头文件中。它从标准输入(通常是键盘)读取一个字符,但需要用户按下回车键才会读取。例如:
#include <stdio.h>
int main()
{char ch;printf("请按一个键并回车:");ch = getchar();printf("你按下的键是:%c\n", ch);return 0;
}
上下左右键盘控制
检测特殊键码(在getch函数基础上):在一些编译器环境下,上下左右键等特殊键在getch函数读取时会返回多个字节的值。例如,在某些实现中,上箭头键可能返回224和72两个字节的值(先返回224作为转义序列的开始,然后返回72表示上箭头)。可以通过判断这些值来实现上下左右键的控制。例如:
#include <stdio.h>
#include <conio.h>
int main()
{int ch;printf("请按上下左右键:");ch = getch();if (ch == 224){ch = getch();if (ch == 72)printf("你按下了上箭头键。\n");else if (ch == 80)printf("你按下了下箭头键。\n");else if (ch == 75)printf("你按下了左箭头键。\n");else if (ch == 77)printf("你按下了右箭头键。\n");}elseprintf("你按下的不是上下左右键。\n");return 0;
}
定位光标
在控制台中使用gotoxy函数
(非标准函数):在一些编译器环境下,可以使用gotoxy函数来定位光标位置。这个函数通常也在<conio.h>
头文件中。它的参数一般是横坐标(列数)和纵坐标(行数)。例如,将光标定位到控制台的 (5, 3) 位置(假设从 (0, 0) 开始计数):
#include <stdio.h>
#include <conio.h>
int main()
{gotoxy(5, 3);printf("光标定位在此处。");return 0;
}
在标准 C 语言中实现类似功能(通过控制字符序列):在标准 C 语言中,可以利用终端控制字符序列来实现类似的光标定位效果。例如,在一些终端模拟器中,\033[%d;%dH这样的控制字符序列可以用来定位光标,其中%d分别代表行和列的位置。可以通过printf函数输出这个控制字符序列来定位光标:
#include <stdio.h>
int main()
{int row = 3, col = 5;printf("\033[%d;%dH", row, col);printf("光标定位在此处。");return 0;
}
基于AI的学习
其他(感悟、思考等,可选)
我总结了一些文件操作的注意事项:
文件打开错误
错误表现:
最常见的是返回空指针(NULL)。当使用fopen函数打开文件时,如果文件不存在(在使用"r"模式打开时)、没有足够的权限打开文件或者文件名错误等情况,fopen函数会返回NULL。
文件读写错误
错误表现:
对于读取操作,可能会读取到错误的数据或者提前到达文件末尾。例如,使用fread函数读取二进制数据时,如果读取的大小超过了文件剩余的大小,可能会导致程序读取到不期望的数据或者产生错误。对于写入操作,如果磁盘空间不足或者没有写入权限,可能会导致写入失败。
忘记关闭文件
错误表现:
忘记关闭文件可能会导致资源泄漏,特别是在频繁打开和关闭文件的程序中。如果不关闭文件,文件缓冲区中的数据可能不会被正确写入磁盘,而且会占用系统资源,可能会影响程序的性能,甚至在某些情况下导致程序崩溃或出现其他不可预测的错误。
文件定位错误
错误表现:
在使用fseek函数进行文件定位时,如果参数设置错误,可能会导致文件指针定位到错误的位置。例如,偏移量计算错误或者whence参数设置不符合预期,可能会使文件指针超出文件范围或者定位到不正确的位置,从而导致后续的读写操作出现问题。