今日學習內容
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;
}
?
?