基于C語(yǔ)言編寫簡(jiǎn)易的英文統(tǒng)計(jì)和加密系統(tǒng)
前言
耗時(shí)一天一夜寫了一個(gè)簡(jiǎn)易的《英文統(tǒng)計(jì)和加密系統(tǒng)》,實(shí)際上就是對(duì)字符數(shù)組的基本操作的各種使用,其中也牽扯到簡(jiǎn)單的讀寫文件,把結(jié)構(gòu)體存入文本文件等知識(shí)??傮w來(lái)說(shuō),只要在編寫前搭建好一個(gè)思維框架,逐個(gè)實(shí)現(xiàn)功能就輕松的多了。
部分功能、開(kāi)發(fā)環(huán)境與項(xiàng)目結(jié)構(gòu)
部分功能展示:
開(kāi)發(fā)環(huán)境:
我使用的開(kāi)發(fā)環(huán)境是 Visual Stduio 2022(2019版本應(yīng)該更好)。
項(xiàng)目結(jié)構(gòu):
包含兩個(gè)頭文件和對(duì)應(yīng)的源文件, main.c,以及三個(gè)文本文件:
主函數(shù)設(shè)計(jì)
// 英文統(tǒng)計(jì)和加密系統(tǒng) // statistics 統(tǒng)計(jì) // encryption 加密(結(jié)構(gòu)體相關(guān)功能也在此處) #include"statistics.h" #include"encryption.h" int main() { char buf[BUFSIZE]; memset(buf, '0', sizeof(buf)); // 給字符數(shù)組初始化為 '0' showInfo(buf); printf("當(dāng)前字母數(shù):%d\n",countCharacter(buf)); printf("當(dāng)前單詞數(shù):%d\n",countWord(buf)); printf("第12個(gè)字母為:"); show_i(buf, 12); printf("與字母 'b'相比,小于,等于,大于的字母?jìng)€(gè)數(shù)分別為:"); classify_c(buf, 'b'); int x = count_appear(buf, 'y'); printf("字母y(不區(qū)分大小寫)出現(xiàn)的次數(shù)為:%d\n", x); printf("所有y出現(xiàn)的下標(biāo)為:"); int* A = (int*)malloc(sizeof(int) * x +1); int *n = location_index(buf, A, 'y'); for (int i = 0; i < x; i++) { printf("%3d", n[i]); } printf("\n"); encryption(buf, 3); /*puts(buf);*/ printf("將26個(gè)英文字母打包成一個(gè)結(jié)構(gòu)體,附加對(duì)應(yīng)次數(shù)\n"); alphabet chars; Initialize(&chars); printf("計(jì)算字母出現(xiàn)次數(shù)并存入文本文件中:\n"); count_letters(buf, &chars); encrypt en = maxTimes(chars); encrypt minEn = minTimes(chars); printf("出現(xiàn)最多的字母為:%c,對(duì)應(yīng)次數(shù)為:%d\n", en.data, en.num); printf("出現(xiàn)最少的字母為:%c,對(duì)應(yīng)次數(shù)為:%d\n", minEn.data, minEn.num); printf("字母平均出現(xiàn)次數(shù):%.2f\n", averageNum(chars)); int k = 8; char* list = list_k(chars,k); printf("前%d名字母序列為:", k); for (int i = 0; i < k; i++) { printf("%2c", list[i]); } select_sort(chars); //setText(&chars); // 需要更新結(jié)構(gòu)體文本文件時(shí)使用 }
主函數(shù)完全可以使用 循環(huán)+switch-case
來(lái)做一個(gè)菜單,重復(fù)使用功能。
實(shí)現(xiàn)效果已經(jīng)在上文中展示,后序不再展示。
statistics 頭文件以及源文件
statistics.h
#pragma once // 避免重復(fù)包含頭文件 #include<stdio.h> #include<stdlib.h> #include<string.h> #define BUFSIZE 512 // 獲取原文長(zhǎng)度 int get_length(char* buf); // 獲取文本的原文內(nèi)容 void getText(char *buf); // 得到原文內(nèi)容 void showInfo(char *buf); // 統(tǒng)計(jì)原文字母?jìng)€(gè)數(shù) int countCharacter(char* buf); // 統(tǒng)計(jì)原文單詞個(gè)數(shù) int countWord(char* buf); // 顯示原文第i個(gè)單詞 void show_i(char* buf,int i); // 根據(jù)字符c的大小,分為三部分 void classify_c(char* buf, char c); // 定位值為c的下標(biāo) int* location_index(char* buf, int* index,char c); // 字符c的出現(xiàn)次數(shù) int count_appear(char* buf, char c);
statistics.c
#include"statistics.h" // 獲取原文有效長(zhǎng)度 int get_length(char* buf) { int len = 0; for (int i = 0; i < BUFSIZE && buf[i] != '0'; i++) { len++; } return len; } //用子函數(shù)實(shí)現(xiàn)從文本文件讀取原文的操作 void getText(char *buf) { FILE* file; file = fopen("myfile.txt", "r"); if (file == NULL) { printf("打開(kāi)文件失敗!"); exit(-1); } char arr[BUFSIZE]; memset(arr, '0', sizeof(arr)); fgets(arr, sizeof(arr), file); fclose(file); strcpy(buf, arr); } //1.定義一字符數(shù)組word,用戶輸入原文或從一文本文件讀入(調(diào)用子函數(shù))原文(一段英文), // 輸出顯示該原文,以及其總長(zhǎng)度。 void showInfo(char* buf) { printf("1.輸入原文:\n"); printf("2.讀取原文\n"); int choice = 0; scanf("%d", &choice); rewind(stdin); // 清空緩沖區(qū) if (choice == 1) { char arr[BUFSIZE]; memset(arr, '0', sizeof(arr)); fgets(arr, sizeof(arr), stdin); strcpy(buf, arr); } else if (choice == 2) { getText(buf); } else { printf("請(qǐng)正確選擇獲取原文方式!"); exit(-1); } int sum = get_length(buf); if (choice==2) printf("總長(zhǎng)度為:%d\n", --sum); // 去掉自帶的 . else printf("總長(zhǎng)度為:%d\n", sum-2); // fgets會(huì)多讀一個(gè)字符 printf("原文:%s\n", buf); } //3.用子函數(shù)實(shí)現(xiàn)統(tǒng)計(jì)原文中的字母?jìng)€(gè)數(shù)。 int countCharacter(char* buf) { int i; int count = 0; for (i = 0; i < BUFSIZE&&buf[i]!= '0'; i++) { if (buf[i] >= 'a' && buf[i] <= 'z' || buf[i] >= 'A' && buf[i] <= 'Z') { count++; } } return count; } //4.用子函數(shù)實(shí)現(xiàn)統(tǒng)計(jì)原文中的單詞個(gè)數(shù)。 int countWord(char* buf) { int i; int count = 0; for (i = 1; i < BUFSIZE&&buf[i]!='0'; i++) { if (buf[i] == ' ' &&(buf[i - 1] >= 'a' && buf[i - 1] <= 'z' || buf[i - 1] >= 'A' && buf[i - 1] <= 'Z')) count++; } if (buf[i - 1] >= 'a' && buf[i - 1] <= 'z' || buf[i - 1] >= 'A' && buf[i - 1] <= 'Z') count++; return count; } //5.定義一子函數(shù),輸入任一下標(biāo)值i,檢查i的輸入合法性, // 合法輸出顯示word的第i個(gè)字母,否則輸出“輸入i不合法”。 void show_i(char* buf,int i) { int len = countCharacter(buf); if (i<1 || i>len) { printf("輸入i不合法\n"); exit(-1); } int index = 0; // 記錄當(dāng)前字母位序 for (int j = 0; j < BUFSIZE && buf[j] != '0'; j++) { if (buf[j] >= 'a' && buf[j] <= 'z' || buf[j] >= 'A' && buf[j] <= 'Z') { ++index; if (index == i) { printf("%c\n", buf[j]); return; } } } } //6.定義一子函數(shù),輸入一字母c, 分別輸出word中大于字母c的個(gè)數(shù)和小于字母c的個(gè)數(shù), // 以及等于字母c的個(gè)數(shù)。 void classify_c(char* buf, char c) { char arr[BUFSIZE]; memset(arr, '0', sizeof(arr)); int index = 0; // 記錄當(dāng)前字母位序 for (int j = 0; j < BUFSIZE && buf[j] != '0'; j++) { if (buf[j] >= 'a' && buf[j] <= 'z' || buf[j] >= 'A' && buf[j] <= 'Z') { arr[index++] = buf[j]; } } // 冒泡排序(升序) for (int i = 0; i < index; i++) { char flag = 'f';// 標(biāo)志位 for (int j = index-1; j > i; j--) { if (arr[j] < arr[j - 1]) { flag = 't'; char ch = arr[j]; arr[j]=arr[j-1]; arr[j - 1] = ch; } } if (flag == 'f') break; } int l, h, e,i; for (l = 0, h = 0, e = 0, i = 0; i < index; i++) { if (arr[i] < c) l++; else if (arr[i] == c) e++; else break; } h = index - l - e; printf("little:%d equal:%d high:%d\n", l, e, h); } //7.定義一子函數(shù),實(shí)現(xiàn)字符查找功能:判定該字母是否存在, // 是則返回每一個(gè)出現(xiàn)位置的下標(biāo)(或者首次出現(xiàn)的下標(biāo)位置),否則返回 - 1。 int* location_index(char* buf, int *index,char c) { int i; int in = 0; char flag = 'f';// 如果最終還是f,說(shuō)明找不到該字母 for (i = 0; i < BUFSIZE && buf[i] != '0'; i++) { if (buf[i] == c||c == buf[i]+32||c==buf[i]-32) index[in++] = i; flag = 't'; } if (flag == 'f') return -1; return index; } //8.定義一子函數(shù),實(shí)現(xiàn)輸入一字母,統(tǒng)計(jì)原文中該字母的出現(xiàn)次數(shù)(字母不區(qū)分大小寫, 實(shí)現(xiàn)合并計(jì)數(shù)) // 并返回。函數(shù)中需要有對(duì)輸入的字母是否輸入異常判定和捕獲操作,并在主程序中進(jìn)行輸入錯(cuò)誤提示。 int count_appear(char* buf, char c) { if (!(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')) { printf("當(dāng)前字符為%c,請(qǐng)輸入正確字母\n", c); exit(-1); } int i; int count = 0; for (i = 0; i < BUFSIZE && buf[i] != '0'; i++) { if (c == buf[i] || c == buf[i] + 32 || c == buf - 32) count++; } return count; }
encryption 頭文件以及源文件
encryption.h
#pragma once #include<stdio.h> #include<string.h> #include<stdlib.h> // 字母以及出現(xiàn)次數(shù)的結(jié)構(gòu)體 typedef struct { char data; // 顯示字母 int num; // 出現(xiàn)次數(shù) }encrypt; typedef struct { encrypt letters[26]; }alphabet; // 初始化字母表 void Initialize(alphabet *chars); // 計(jì)算各個(gè)字母的出現(xiàn)次數(shù) void count_letters(char* buf, alphabet* chars); // 存入結(jié)構(gòu)體文本文件 void setText(alphabet *chars); // 返回出現(xiàn)次數(shù)最多的字母 encrypt maxTimes(alphabet chars); // 返回出現(xiàn)次數(shù)最少的字母 encrypt minTimes(alphabet chars); // 計(jì)算字母出現(xiàn)的平均次數(shù) float averageNum(alphabet chars); // 出現(xiàn)前k名的字母序列 char* list_k(alphabet chars, int k); // 選擇升序或者降序排序 void select_sort(alphabet chars); // 加密算法,根據(jù)n的位置循環(huán)后移 void encryption(char* buf, int n); // 存入加密的文本文件 void setEncryptText(char* buff);
encryption.c
#include"encryption.h" #include"statistics.h" //9.將26個(gè)英文字母和其對(duì)應(yīng)的出現(xiàn)次數(shù)打包定義為一個(gè)結(jié)構(gòu)體類型來(lái)存儲(chǔ)。 // 初始化結(jié)構(gòu)體數(shù)組 void Initialize(alphabet* chars) { int k = 0; char c = 'a'; for (int i = 0; i < 26; i++) { chars->letters[i].num = k; chars->letters[i].data = c + i; } } //10.設(shè)計(jì)實(shí)現(xiàn)一新的子函數(shù),針對(duì)讀入的原文,統(tǒng)計(jì)出26個(gè)英文字母在單詞中出現(xiàn)的次數(shù), //并統(tǒng)一存儲(chǔ)到9定義的結(jié)構(gòu)體數(shù)組中,然后完成11到16的操作。 void count_letters(char* buf, alphabet* chars) { printf("1.輸入原文:\n"); printf("2.讀取原文\n"); int choice = 0; int sum = 0; scanf("%d", &choice); rewind(stdin); // 清空緩沖區(qū) if (choice == 1) { char arr[BUFSIZE]; memset(arr, '0', sizeof(arr)); fgets(arr, sizeof(arr), stdin); strcpy(buf, arr); } else if (choice == 2) { getText(buf); } else { printf("請(qǐng)正確選擇獲取原文方式!"); exit(-1); } char arr[BUFSIZE]; // 最終轉(zhuǎn)化為全部字母 memset(arr, '0', sizeof(arr)); int index = 0; // 記錄當(dāng)前字母位序 for (int j = 0; j < BUFSIZE && buf[j] != '0'; j++) { if (buf[j] >= 'a' && buf[j] <= 'z' || buf[j] >= 'A' && buf[j] <= 'Z') { arr[index++] = buf[j]; } } for (int i = 0; i < index; i++) { for (int j = 0; j < 26; j++) { if (arr[i] == chars->letters[j].data || arr[i] + 32 == chars->letters[j].data) chars->letters[j].num++; } } } //11.將結(jié)構(gòu)體數(shù)組結(jié)果存儲(chǔ)到一文本文件。 void setText(alphabet* chars) { FILE* fp; fopen_s(&fp, "struct.txt", "wt+"); //打開(kāi)文件 for (int i = 0; i < 26; i++) //將N條信息存儲(chǔ)進(jìn)去 { fprintf(fp, "%d %d\n", chars->letters[i].data, chars->letters[i].num); } fclose(fp); //關(guān)閉文件 //encrypt buff[26]; //FILE* fpp; //fopen_s(&fpp, "struct.txt", "rb"); //fread(buff, sizeof(encrypt), 26, fpp); // 將N條消息全部從文件中讀取出來(lái) //fclose(fpp); } //12.設(shè)計(jì)一子函數(shù):返回出現(xiàn)次數(shù)最多的字母和對(duì)應(yīng)次數(shù)。 encrypt maxTimes(alphabet chars) { int max = chars.letters[0].num; int i, index; for (i = 1, index = 0; i < 26; i++) { if (max < chars.letters[i].num) { max = chars.letters[i].num; index = i; } } return chars.letters[index]; } //13.設(shè)計(jì)一子函數(shù):返回出現(xiàn)次數(shù)最少的字母和對(duì)應(yīng)次數(shù)。 encrypt minTimes(alphabet chars) { int min = chars.letters[0].num; int i, index; for (i = 1, index = 0; i < 26; i++) { if (min > chars.letters[i].num) { min = chars.letters[i].num; index = i; } } return chars.letters[index]; } //14.設(shè)計(jì)一子函數(shù):返回26個(gè)字母的平均出現(xiàn)次數(shù)。 float averageNum(alphabet chars) { float avg = 0.0; for (int i = 0; i < 26; i++) { avg += chars.letters[i].num; } avg /= 26; return avg; } //15. 設(shè)計(jì)一子函數(shù):輸入數(shù)字k,返回出現(xiàn)次數(shù)前k名的字母序列 char* list_k(alphabet chars, int k) { if (k < 1 || k>26) exit(-1); char* list = (char*)malloc(sizeof(char) * k); // 冒泡排序 for (int i = 0; i < 26; i++) { char flag = 'f'; for (int j = 25; j > i; j--) { if (chars.letters[j].num > chars.letters[j - 1].num) { flag = 't'; encrypt temp = chars.letters[j]; chars.letters[j] = chars.letters[j - 1]; chars.letters[j - 1] = temp; } } if (flag == 'f') break; } for (int i = 0; i < k; i++) { list[i] = chars.letters[i].data; } return list; } //16.定義一排序子函數(shù),實(shí)現(xiàn)對(duì)結(jié)構(gòu)體數(shù)組結(jié)果按照出現(xiàn)次數(shù)進(jìn)行升序或降序排列 //(由用戶在運(yùn)行時(shí)選擇排序方式), 輸出排序結(jié)果以及對(duì)應(yīng)的字母。 void select_sort(alphabet chars) { printf("\n1.升序排列\(zhòng)n2.降序排列\(zhòng)n"); int choice = 0; scanf("%d", &choice); if (choice == 2) { for (int i = 0; i < 26; i++) { char flag = 'f'; for (int j = 25; j > i; j--) { if (chars.letters[j].num > chars.letters[j - 1].num) { flag = 't'; encrypt temp = chars.letters[j]; chars.letters[j] = chars.letters[j - 1]; chars.letters[j - 1] = temp; } } if (flag == 'f') break; } } else if (choice == 1) { for (int i = 0; i < 26; i++) { char flag = 'f'; for (int j = 25; j > i; j--) { if (chars.letters[j].num < chars.letters[j - 1].num) { flag = 't'; encrypt temp = chars.letters[j]; chars.letters[j] = chars.letters[j - 1]; chars.letters[j - 1] = temp; } } if (flag == 'f') break; } } else { printf("請(qǐng)正確選擇排序規(guī)則!"); exit(-1); } printf("排序結(jié)果為:"); for (int i = 0; i < 26; i++) { printf("%2c", chars.letters[i].data); } } //17.用子函數(shù)實(shí)現(xiàn)將讀取的原文按規(guī)則加密后存入另一字符數(shù)組中。 //電文加密 : 問(wèn)題描述:為使電文保密,常按一定規(guī)律將其轉(zhuǎn)換成密文后發(fā)送, //收?qǐng)?bào)人再按約定的規(guī)律將其譯回原文。設(shè)定加密規(guī)則為: //每個(gè)字母變成其后的第n(n由用戶輸入指定)個(gè)字母,如A變成其后第n個(gè)字母….。 //說(shuō)明 : 只對(duì)原文中的英文字母加密, 其他非英文字母要原樣保留。 void encryption(char* buf, int n) { n %= 26; // 確保英文字母加密后還是英文字母 int i; int len = get_length(buf); char* arr = (char*)malloc(len * sizeof(char)); memset(arr, '0', sizeof(arr));// 初始化 for (i = 0; i < len; i++) { if (buf[i] >= 'a' && buf[i] <= 'z' || buf[i] >= 'A' && buf[i] <= 'Z') { if (buf[i] + n > 'z') { arr[i] = buf[i] + n - 26; } else if (buf[i] <= 'Z' && buf[i] + n > 'Z') { arr[i] = buf[i] + n - 'Z' + 'A'-1; } else { arr[i] = buf[i] + n; } } else { arr[i] = buf[i]; } } printf("加密后:%s\n", arr); setEncryptText(arr); } //18.用子函數(shù)實(shí)現(xiàn)將密文存入密文文本文件中。 void setEncryptText(char* buff) { FILE* fp; fp = fopen("encryption.txt", "wt+"); if (fp == NULL) { printf("打開(kāi)文件失敗!"); exit(-1); } fputs(buff, fp); fclose(fp); }
myfile.txt文件中可自行輸入密文(26個(gè)英文字母大小寫,各種符號(hào),數(shù)字等等);
struct.txt文件有26行,對(duì)應(yīng)著原文中26個(gè)英文字母出現(xiàn)的次數(shù)以及ASCII碼值;
encryption.txt文件是myfile.txt文件中的字母通過(guò)循環(huán)后移 n 位得到,其中的難點(diǎn)在于大寫字母后移超過(guò)Z時(shí)的處理方法,這點(diǎn)大家可以在encryption.c文件中的encryption函數(shù)中獲得靈感。
到此這篇關(guān)于基于C語(yǔ)言編寫簡(jiǎn)易的英文統(tǒng)計(jì)和加密系統(tǒng)的文章就介紹到這了,更多相關(guān)C語(yǔ)言英文統(tǒng)計(jì)和加密系統(tǒng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)重載矩陣的部分運(yùn)算符
這篇文章主要為大家詳細(xì)介紹了如何利用C++實(shí)現(xiàn)重載矩陣的部分運(yùn)算符,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C++有一定幫助,需要的可以參考一下2022-10-10基于Matlab實(shí)現(xiàn)多目標(biāo)粘液霉菌算法的示例代碼
多目標(biāo)粘液霉菌算法(MOSMA),這是最近開(kāi)發(fā)的粘液霉菌算法(SMA)的多目標(biāo)變體,用于處理工業(yè)中的多目標(biāo)優(yōu)化問(wèn)題。本文將用Matlab實(shí)現(xiàn)這一算法,需要的可以參考一下2022-05-05atoi和itoa函數(shù)的實(shí)現(xiàn)方法
本文介紹了,atoi和itoa函數(shù)的實(shí)現(xiàn)方法,需要的朋友可以參考一下2013-03-03