Day1:标准IO介绍及缓冲区
1、缓冲区实验
Day2:标准IO:文件的打开、关闭
1、打开一个不存在的文件,分别使用perror和strerror打印错误信息
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main(int argc, const char *argv[])
{
FILE *fp;
int fpret;
fp = fopen("1.txt","rb");
if(fp == NULL){
//printf("Open file Failed\n");
perror("fopne:");
printf("fopen:%s\n",strerror(errno));
}else{
//printf("Open file Success\n");
perror("fopen:");
fpret = fclose(fp);
if(fpret == 0){
printf("file close success\n");
}else{
perror("close");
}
}
return 0;
}
Day3:标准IO的读写(字符、行)
1、按行输出文件实验
#include <stdio.h>
int main(int argc, const char *argv[])
{
FILE *fp;
char *ret;
int retn;
char buff[100];
fp = fopen("1.txt","a+");
if(fp == NULL){
perror("fopen");
return 0;
}
/* ret = fgets(buff,5,fp);
if(ret == NULL){
perror("fgets");
fclose(fp);
return 0;
}
printf("buff=%s\n",buff);
*/
retn = fputs("hello world",fp);
if(retn == -1){
perror("fputs");
}
fclose(fp);
return 0;
}
Day4:标准IO读写:二进制方式
1、使用标准IO写2个学生的结构体数据到文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student{
char name[50];
int age;
char sex[10];
};
int main(int argc, const char *argv[])
{
FILE *fp;
size_t ret,ret1,rten,rten1;
struct student stu;
struct student stu1;
fp = fopen("1.bin","w");
if(fp == NULL){
perror("fopen");
return 0;
}
strcpy(stu.name,"YGX");
stu.age = 21;
strcpy(stu.sex,"male");
strcpy(stu1.name,"ZZZ");
stu1.age = 57;
strcpy(stu1.sex,"fmale");
ret = fwrite(&stu,sizeof(stu),1,fp);
ret1 = fwrite(&stu1,sizeof(stu1),1,fp);
if(ret == -1 || ret1 == -1){
perror("fwrite");
goto end;
}else{
printf("write sturct student success\n");
}
fp = fopen("1.bin","r");
if(fp == NULL){
perror("fopen");
return 0;
}
rten = fread(&stu,sizeof(stu),1,fp);
rten1 = fread(&stu1,sizeof(stu1),1,fp);
if(rten == -1 || rten1 == -1){
perror("fread");
goto end;
}
printf("name1=%s,age1=%d,sex1=%s\n",stu.name,stu.age,stu.sex);
printf("name2=%s,age2=%d,sex2=%s\n",stu1.name,stu1.age,stu1.sex);
end:
fclose(fp);
return 0;
}
Day5:流刷新定位
1、流的刷新及定位用到了哪些函数?分别有什么作用?
流的刷新:
int fflush(FILE *fp);
成功时返回0;出错时返回EOF;
将流缓冲区中的数据写入实际的文件;
Linux下只能刷新输出缓冲区,输入缓冲区丢弃;
如果需要输出到屏幕,则函数使用为fflush(stdout);
流的定位:
long ftell(FILE *stream); 定位文件指针的位置
long fseek(FILE *stream, long offset, int whence);
void rewind(FILE *stream);
fseek 参数whence参数:SEEK_SET/SEEK_CUR/SEEK_END
SEEK_SET 从距文件开头 offset 位移量为新的读写位置
SEEK_CUR:以目前的读写位置往后增加 offset 个位移量
SEEK_END:将读写位置指向文件尾后再增加 offset 个位移量
offset参数:偏移量,可正可负
注意事项:
1.当文件的打开使用a模式 fseek函数无效
2.函数rewind(fp) 相当于 fseek(fp,0,SEEK_SET);
3.这三个函数只适用2G以下的文件
Day6:格式化输入输出
1、格式化输入输出用到了哪些函数?分别有什么作用?
格式化输出
int fprintf(FILE *stream, const char *fmt, …); 发送格式化输出到流 stream 中
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE * fp;
fp = fopen ("file.txt", "w+");
fprintf(fp, "%s %s %s %d", "Time", "is", "in", 2023);
fclose(fp);
return(0);
}
编译并运行上面的程序,这将创建文件 file.txt,它的内容如下:
Time is in 2023
int sprintf(char *s, const char *fmt, …); 发送格式化输出到 s 所指向的字符串
#include <stdio.h>
#include <math.h>
int main()
{
char str[100];
sprintf(str, "Pi 的值 = %f", M_PI);
puts(str);
return(0);
}
编译并运行上面的程序,这将产生以下结果:
Pi 的值 = 3.141593
格式化输入
int fscanf(FILE *stream, const char *format, ...); 从流 stream 读取格式化输入
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str1[10], str2[10], str3[10];
int year;
FILE * fp;
fp = fopen ("file.txt", "w+");
fputs("Time is in 2023", fp);
rewind(fp);
fscanf(fp, "%s %s %s %d", str1, str2, str3, &year);
printf("Read String1 |%s|\n", str1 );
printf("Read String2 |%s|\n", str2 );
printf("Read String3 |%s|\n", str3 );
printf("Read Integer |%d|\n", year );
fclose(fp);
return(0);
}
编译并运行上面的程序,这将产生以下结果:
Read String1 |Time| Read String2 |is| Read String3 |in| Read Integer |2023|
int sscanf(const char *str, const char *format, ...); 从 str 指向的字符串读取格式化输入
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int day, year;
char weekday[20], month[20], dtm[100];
strcpy( dtm, "Monday April 10 2023" );
sscanf( dtm, "%s %s %d %d", weekday, month, &day, &year );
printf("%s %d, %d = %s\n", month, day, year, weekday );
return(0);
}
编译并运行上面的程序,这将产生以下结果:
April 10, 2023 = Monday
Day7:标准IO练习
1、每隔1秒向文件1.txt写入当前系统时间,行号递增
#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(int argc, const char *argv[])
{
FILE *fp;
time_t ctime;
int linecount;
struct tm *ctimestr;
char buf[22];
fp = fopen("test.txt","a+");
if(fp == NULL){
perror("fopen");
return 0;
}
while(fgets(buf,22,fp) != NULL){
if(buf[strlen(buf) - 1] == '\n'){
linecount++;
}
}
while(1){
ctime = time(NULL);
// printf("ctime = %d\n",(int)ctime);
ctimestr = localtime(&ctime);
printf("%04d-%02d-%02d %02d:%02d:%02d\n",ctimestr->tm_year+1900,ctimestr->tm_mon+1,ctimestr->tm_mday,
ctimestr->tm_hour,ctimestr->tm_min,ctimestr->tm_sec);
fprintf(fp,"%d, %04d-%02d-%02d %02d:%02d:%02d\n",linecount,ctimestr->tm_year+1900,ctimestr->tm_mon+1,ctimestr->tm_mday,
ctimestr->tm_hour,ctimestr->tm_min,ctimestr->tm_sec);
fflush(fp);
linecount++;
sleep(1);
}
fclose(fp);
return 0;
}
Day8:文件IO(概念、打开、读、写、关闭)
1、使用文件IO实现“每隔1秒向文件1.txt写入当前系统时间,行号递增”
#include<stdio.h>
#include<time.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(int argc, const char *argv[])
{
int fd;
time_t ctime;
struct tm *ctimestr;
int ret;
int linecount = 0;
char buf2[100];
fd = open("1.txt",O_RDWR|O_CREAT|O_APPEND, 0666);
if(fd==-1){
printf("open failed\n");
return 0;
}
while(read(fd,buf2,strlen(buf2)) != 0){
if (buf2[strlen(buf2)-1] == '\n'){
linecount++;
}
}
while(1){
ctime = time(NULL);
ctimestr = localtime(&ctime);
printf("%d, %04d-%02d-%02d %02d:%02d:%02d\n",linecount,ctimestr->tm_year+1900,ctimestr->tm_mon+1,ctimestr->tm_mday,
ctimestr->tm_hour,ctimestr->tm_min,ctimestr->tm_sec);
sprintf(buf2,"%d, %04d-%02d-%02d %02d:%02d:%02d\n",linecount,ctimestr->tm_year+1900,ctimestr->tm_mon+1,ctimestr->tm_mday,
ctimestr->tm_hour,ctimestr->tm_min,ctimestr->tm_sec);
ret = write(fd,buf2,strlen(buf2));
if(ret<0){
perror("write");
close(fd);
}
fflush(fd);
linecount++;
sleep(1);
}
close(fd);
}
Day9:文件IO(概念、打开、读、写、关闭)
1、遍历一个文件夹下所有文件,并打印文件大小和日期
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <time.h>
int main(int argc, const char *argv[])
{
DIR * dir;
struct dirent *dent;
struct stat buf;
dir = opendir("/home/linux/lv3/linklist1/");
if(dir == NULL){
perror("opendir");
return 0;
}
while((dent = readdir(dir)) != NULL){
stat(dent->d_name,&buf);
struct tm *t = localtime(&buf.st_ctime);
printf("create time>%04d-%02d-%02d %02d:%02d:%02d ",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
printf("name>%-16s size>%d\n",dent->d_name,(int)buf.st_size);
}
closedir(dir);
return 0;
}
Day10:静态库和动态库的使用
1、静态库和动态库都有什么特点?他们的区别是什么?
静态库:
特点:
一般扩展名为(.a或.lib),这类的函数库通常扩展名为libxxx.a或xxx.lib 。
静态库在编译时被链接到目标文件中,程序运行时不需要再额外加载库文件。
可以在不同平台上编译相同的源代码,而无需考虑库的兼容性问题。
程序的执行速度比动态库快,因为所有的库函数都在编译时被链接到可执行文件中。
静态库的使用非常简单,只需要将库文件和头文件包含在项目中即可。
区别:
静态库的体积比较大,因为它包含了所有需要的函数和代码。
如果多个程序都使用同一个静态库,那么每个程序都会有一份完整的库文件,会占用较多的磁盘空间。
如果静态库更新了,需要重新编译程序才能使用新的库函数。
动态库:
特点:
动态函数库的扩展名一般为(.so或.dll),这类函数库通常名为libxxx.so或xxx.dll 。
动态库在程序运行时才会被加载,可以在程序运行时动态地链接和卸载库文件。
多个程序可以共享同一个动态库,节省磁盘空间。
动态库的更新只需要替换库文件,程序不需要重新编译。
动态库可以提供插件功能,允许程序在运行时加载外部库。
区别:
动态库的执行速度比静态库慢,因为需要在程序运行时加载和链接库文件。
动态库的使用相对复杂,需要在程序中显式地加载和卸载库文件。
动态库的兼容性问题比较复杂,不同操作系统和编译器可能需要不同版本的库文件。