今日学习内容
1. 行输入函数安全实践
(1) fgets vs gets
函数 | 安全特性 | 换行符处理 | 缓冲区保护 |
---|---|---|---|
fgets | 指定读取长度(size-1 ) | 保留\n 并添加\0 | 安全(防溢出) |
gets | 无长度限制 | 将\n 替换为\0 | 危险 |
2. Linux标准文件流
文件流 | 符号 | 设备 | |
---|---|---|---|
标准输入 | stdin | 键盘 | |
标准输出 | stdout | 显示器 | |
标准错误 | stderr | 显示器 |
3. 块数据操作核心函数
(1) fwrite数据写入
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
- 参数解析:
ptr
:数据源首地址size
:单个元素字节数(如sizeof(int)
)nmemb
:写入元素个数stream
:目标文件流
- 返回值:实际写入元素个数(非字节数)
(2) fread数据读取
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
- 返回值语义:
- 成功:实际读取元素个数
- 文件末尾:0
- 错误:元素数小于请求值
4. 文件流定位三剑客
函数 | 原型 | 核心功能 |
---|---|---|
fseek | int fseek(FILE*, long, int) | 重定位文件指针 |
ftell | long ftell(FILE*) | 获取当前偏移量(字节) |
rewind | void rewind(FILE*) | 重置指针到文件开头 |
fseek(fp, 100, SEEK_SET); // 从开头偏移100字节
fseek(fp, -50, SEEK_CUR); // 从当前位置回退50字节
fseek(fp, 0, SEEK_END); // 定位到文件末尾
5. 高级文件操作技巧
//fread#include <stdio.h>struct stu
{int id;char name[32];int score;
};int main(void)
{FILE *fp = fopen("./1.txt", "r");if(NULL == fp){printf("open error\n");return -1;}struct stu s[10];size_t cnt = fread(s, sizeof(struct stu), 5, fp);printf("%ld\n", cnt);for(int i = 0;i < cnt; ++i){printf("%d %s %d\n", s[i].id, s[i].name, s[i].score);}fclose(fp);return 0;
}
//fwrite#include <stdio.h>struct stu
{int id;char name[32];int score;
};int main(int argc, const char *argv[])
{FILE *fp = fopen("./1.txt", "r");if(NULL == fp){printf("open error\n");return -1;}struct stu s[5] = {{1, "a", 12}, {2,"b", 34},{3, "c", 56}, {4,"d", 78},{5, "e", 90},};size_t cnt = fwrite(s, sizeof(struct stu), 5, fp);printf("%ld\n", cnt);fclose(fp);return 0;
}
//文件大小
#include <stdio.h>int main(void)
{FILE *fp = fopen("./1.txt", "r");if(NULL == fp){printf("open error\n");return -1;}fseek(fp, 0, SEEK_END);long offset = ftell(fp);printf("%ld\n", offset);fseek(fp, 0, SEEK_SET);fclose(fp);return 0;}
//copy#include <stdio.h>int main(void)
{ FILE *fpsrc = fopen("./1.txt", "r");FILE *fpdest = fopen("./2.txt", "w");if(NULL == fpsrc || NULL == fpdest){printf("open error\n");return -1;}fseek(fpsrc, 0, SEEK_END);long offset = ftell(fpsrc);fseek(fpsrc, 0, SEEK_SET);fseek(fpdest, offset, SEEK_SET);fputc(0, fpdest);fseek(fpdest, 0, SEEK_SET);char buffer[100] = {0};size_t cnt = fread(buffer, offset, 1, fpsrc);fwrite(buffer, offset, 1, fpdest);fclose(fpdest);fclose(fpsrc);return 0;}
//打印bmp图片的文件信息和图像信息#include <stdio.h>#pragma pack(1)//bmp文件相关信息
typedef struct tagBITMAPFILEHEADER {short bfType; // 文件类型标志int bfSize; // 文件大小,单位为字节short bfReserved1; // 保留字节short bfReserved2; // 保留字节int bfOffBits; // 数据偏移量,即实际图像数据开始的位置
}Bmp_file_head_t;
//bmp图像信息
typedef struct tagBITMAPINFOHEADER {int biSize; // BITMAPINFOHEADER的大小,单位为字节int biWidth; // 位图的宽度,单位为像素int biHeight; // 位图的高度,单位为像素short biPlanes; // 目标设备的位平面数,必须为1short biBitCount; // 每像素位数(颜色深度)int biCompression; // 图像压缩类型int biSizeImage; // 图像大小,单位为字节int biXPelsPerMeter;// 水平分辨率,单位为像素/米int biYPelsPerMeter;// 垂直分辨率,单位为像素/米int biClrUsed; // 实际使用颜色数int biClrImportant; // 重要颜色数
}Bmp_info_t;
#pragma pack()int get_bmp_head_info(const char *bmpname, Bmp_file_head_t *pheadinfo, Bmp_info_t *pbmpinfo)
{FILE *fp = fopen(bmpname, "r");if (NULL == fp){printf("fopen error\n");return -1;}fread(pheadinfo, sizeof(Bmp_file_head_t), 1, fp);fread(pbmpinfo, sizeof(Bmp_info_t), 1, fp);fclose(fp);return 0;
}int main(int argc, const char *argv[])
{Bmp_file_head_t headinfo;Bmp_info_t bmpinfo;get_bmp_head_info("./3.bmp", &headinfo, &bmpinfo);printf("sizeof(Bmp_file_head_t) = %ld\n", sizeof(Bmp_file_head_t));printf("sizeof(Bmp_info_t) = %ld\n", sizeof(Bmp_info_t));printf("biWidth = %d, biHeight = %d, biBitCount = %d\n", bmpinfo.biWidth, bmpinfo.biHeight, bmpinfo.biBitCount);return 0;
}
//字典#include <stdio.h>
#include <string.h>
char line[500];
char word[50];
int reserchWord(char *word)
{FILE *fp = fopen("./dict.txt", "r");if(NULL == fp){printf("open error\n");return -1;}int t = 0;while(NULL != fgets(line, sizeof(line), fp)){char *find = strtok(line, " ");if(NULL == find){printf("errror\n");continue;}if(0 == strcmp(find, word)){t = 1;printf("find\n");printf("解释:%s\n", line + strlen(find) + 1);break;}}if(t == 0){printf("not found\n");}fclose(fp);return 0;
}int main(void)
{printf(" 字典 \n");printf("输入不超过五十个字符的单词\n");printf("输入.quit中断程序\n");while(1){char s[50] = {0};scanf("%s", s);if(0 == strcmp(s, ".quit")){printf("over\n");break;}reserchWord(s); }return 0;
}