一個考驗c語言和資料結構功底的小專案
阿新 • • 發佈:2019-01-10
想測一下自己c語言學習水平的朋友可以做一下這個專案試試,能做出來說明c語言已經入門了
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct Node
{
char data[20]; //指名字
struct Node *next;
}Node;
//把每一個資料夾看成一個頭結點,存放在指標數組裡
int v = 0; //定義全域性變數v便於建立資料夾
Node *a[100] = {NULL}; //定義一個指標陣列指向各個資料夾
void caidan1() //輸出選單
{
printf(" 選擇式選單\n");
printf("+====================================+\n");
printf("+ +\n");
printf("+ 1:建立資料夾 +\n");
printf("+ +\n");
printf("+ 2:檢視資料夾 +\n" );
printf("+ +\n");
printf("+ 3:刪除資料夾 +\n");
printf("+ +\n");
printf("+ 4:對檔案操作 +\n");
printf("+ +\n");
printf("+ 0:退出程式 +\n" );
printf("+ +\n");
printf("+====================================+\n");
}
void caidan2() //輸出對檔案操作選單
{
printf("+====================================+\n");
printf("+ +\n");
printf("+ 1:建立檔案 +\n");
printf("+ +\n");
printf("+ 2:刪除檔案 +\n");
printf("+ +\n");
printf("+ 3:顯示某資料夾中的檔案 +\n");
printf("+ +\n");
printf("+ 4:對檔案內容操作 +\n");
printf("+ +\n");
printf("+ 0:返回上層操作 +\n");
printf("+ +\n");
printf("+====================================+\n");
}
void caidan3()
{
printf("===============================================================\n");
printf(" 1-讀取程式碼資訊 2-增加一行程式碼 3-刪除一行程式碼 4-修改一行程式碼\n");
printf(" 5-按程式碼查詢 6-按標號查 0-返回上層操作\n");
printf("===============================================================\n");
}
int search_wenjianjia(char temp1[]) //根據資料夾名稱搜尋資料夾
{
int i; //尋找所在的資料夾,即頭結點
for (i = 0; i < v; i++)
{
if (a[i] != NULL && strcmp(a[i]->data, temp1) == 0)
return i; //搜尋成功返回資料夾的位置
}
if (i == v)
{
return -1; //搜尋失敗返回-1
}
}
Node *search_wenjian(int i, char temp2[]) //根據資料夾位置和檔名稱搜尋檔案
{
Node *q = a[i];
while (q->next != NULL)
{
if (strcmp(q->next->data, temp2) == 0)
return q; //檔案存在返回上一結點
else
q = q->next;
}
return NULL; //檔案不存在返回NULL
}
void create_folio() //建立資料夾
{
printf("請輸入你要建立的資料夾的名稱:");
Node *head = (Node*)malloc(sizeof(Node));
gets(head->data);
if (search_wenjianjia(head->data) != -1) //判斷是否已經存在同名資料夾
{
printf("此資料夾已存在\n");
return;
}
a[v] = head;
a[v]->next = NULL;
v++;
}
void look_folio() //檢視資料夾
{
printf("資料夾如下所示:\n");
int i, s = 1; //s用來判斷是否有資料夾
for (i = 0; i < v; i++)
{
if (a[i]->data != NULL)
{
printf("%s ",a[i]->data);
s = 0;
}
}
if ( s == 1)
printf("無資料夾\n");
printf("\n");
}
void delete_folio() //刪除資料夾
{
printf("請輸入你要刪除的資料夾名稱:");
char temp1[20];
gets(temp1);
int i = search_wenjianjia(temp1); //搜尋資料夾位置
if (i == -1)
printf("此資料夾不存在\n");
else
{
free(a[i]);
a[i] = NULL;
}
}
void create_file() //建立檔案
{
char ch, temp1[20], temp2[20]; // temp1為資料夾名字,temp2為檔名字。
printf("請輸入你要建立的檔案所在資料夾的名字:");
gets(temp1);
int i = search_wenjianjia(temp1); //判斷輸入的資料夾是否存在
if (i == -1)
{
printf("輸入的資料夾不存在\n");
return;
}
printf("請輸入你要建立的檔案的名字:");
gets(temp2);
if (search_wenjian(i, temp2) != NULL) //判斷輸入的檔名是否已經存在
{
printf("輸入的檔名已存在\n");
return;
}
FILE *t;
if ((t = fopen(temp2, "w")) == NULL) //開啟輸出檔案並使t指向此檔案
{
printf("無法開啟此檔案\n");
return ;
}
printf("請輸入檔案內容(以$結束)\n");
ch = getchar();
while (ch != '$')
{
fputc(ch,t);
ch = getchar();
}
Node *p = (Node *)malloc(sizeof(Node));
Node *q;
q = a[i];
strcpy(p->data, temp2); //傳遞檔名字
p->next = NULL;
while (q->next != NULL) //把該檔案放在連結串列的後面
{
q = q->next;
}
q->next = p;
fclose(t); //關閉檔案
}
void delete_file() //刪除檔案
{
char temp1[20], temp2[20]; // 分別存放資料夾名和檔名
printf("請輸入你要刪除的檔案所在資料夾的名字:");
gets(temp1);
int i = search_wenjianjia(temp1); //查詢資料夾位置並判斷資料夾是否存在
if (i == -1)
{
printf("輸入的資料夾不存在\n");
return;
}
printf("請輸入你要刪除的檔案的名字:");
gets(temp2);
Node *p = search_wenjian(i, temp2); //搜尋檔案位置同時判斷要刪除的檔案是否存在
if(p == NULL)
{
printf("輸入的檔名不存在,無法刪除\n");
return;
}
Node *q;
q = p->next;
p->next = p->next->next;
if (remove(q->data) == 0) //判斷是否刪除成功
printf("刪除成功\n");
else
printf("刪除失敗\n");
free(q);
q = NULL;
}
void show_file() //顯示某資料夾中的檔案
{
char temp1[20];
printf("請輸入你要顯示的資料夾的名字:");
gets(temp1);
int i = search_wenjianjia(temp1); //搜尋並判斷資料夾是否存在
if (i == -1)
{
printf("輸入的資料夾不存在\n");
return;
}
Node *p = a[i];
if (p->next == NULL) //判斷該資料夾是否為空
{
printf("該資料夾下不存在檔案\n");
return;
}
printf("該資料夾下的檔案分別為:\n"); //輸出該資料夾下所有檔案
while (p->next != NULL)
{
printf("%s ",p->next->data);
p = p->next;
}
printf("\n");
}
void read_file() //讀取程式碼資訊,把一個檔案的資訊輸出出來
{
char temp1[20], temp2[20];
printf("請輸入你要讀取檔案所在的資料夾名:");
gets(temp1);
int i = search_wenjianjia(temp1); //搜尋並判斷資料夾是否存在
if (i == -1)
{
printf("輸入的資料夾不存在\n");
return;
}
printf("請輸入你要讀取的檔名:");
gets(temp2);
Node *p = search_wenjian(i, temp2);
if (p == NULL) //判斷要讀取的檔案是否存在
{
printf("要讀取的檔案不存在\n");
return;
}
char ch; //讀取檔案
FILE *fp;
if((fp=fopen(p->next->data,"r"))==NULL)
{
printf("file cannot be opened\n");
return;
}
while((ch = fgetc(fp)) != EOF)
printf("%c", ch);
fclose(fp);
}
void copy_file(char temp1[], char temp2[]) //把一個檔案的東西複製到另一個檔案中
{
FILE *in, *out;
char ch;
if ((in = fopen(temp1,"r")) == NULL)
{
printf("無法開啟此檔案\n");
return;
}
if ((out = fopen(temp2,"w")) == NULL)
{
printf("無法開啟此檔案\n");
return;
}
while (!feof(in)) //如果未遇到輸入檔案的結束標誌
{
ch=fgetc(in); //從輸入檔案中讀入一個字元,暫時放在變數ch中
fputc(ch,out); //將ch寫到輸出檔案中
}
fclose(in);
fclose(out);
}
int judge_hanghao(char temp[], int x) //按行操作時判斷輸入的行號是否正確
{
FILE *fp;
if ((fp = fopen(temp, "r")) == NULL)
{
printf("無法開啟此檔案\n");
return;
}
char buf[1000];
int linecnt = 0; //用來記錄行號
while (fgets(buf, 1000, fp)) // fgets迴圈讀取,直到檔案最後,才會返回NULL
linecnt++; // 累計行數
fclose(fp);
if (x > linecnt)
return 0;
return 1;
}
void add_a_line_code() //增加一行程式碼
{
char temp1[20], temp2[20]; // 分別為資料夾名稱 檔名稱
printf("請輸入你要操作的檔案所在的資料夾名稱:");
gets(temp1);
int i = search_wenjianjia(temp1); //搜尋並判斷資料夾是否存在
if (i == -1)
{
printf("輸入的資料夾不存在\n");
return;
}
printf("請輸入你要操作的檔名:");
gets(temp2);
Node *p = search_wenjian(i, temp2); //p為檔案的上一結點
if (p == NULL) //判斷要讀取的檔案是否存在
{
printf("要讀取的檔案不存在\n");
return;
}
int x; // 表示在第幾行增加程式碼
printf("你要在第幾行增加程式碼:");
scanf("%d", &x);
getchar();
if (judge_hanghao(p->next->data, x - 1) == 0) //判斷輸入的行號是否正確
{
printf("輸入的行號錯誤\n");
return;
}
char temp3[100]; //存放要增加的程式碼
printf("請輸入你要增加的一行程式碼:");
gets(temp3);
FILE *fp1, *fp2; //把一個檔案的東西複製到另一個檔案中
copy_file(p->next->data, "temp_file");
if((fp1=fopen(p->next->data,"w"))==NULL)
{
printf("file cannot be opened\n");
return;
}
if((fp2=fopen("temp_file","r"))==NULL)
{
printf("file cannot be opened\n");
return;
}
char str[256] = {0};
int t = 0; //用來計算行號
while(t < x - 1) //複製x行前面的部分
{
fgets(str, 256, fp2);
fputs(str, fp1);
t++;
}
fputs(temp3, fp1); //輸入增加的一行
fputs("\n", fp1);
while (fgets(str, 256, fp2) != NULL) //複製剩下的部分
{
fputs(str, fp1);
}
fclose(fp1);
fclose(fp2);
remove("temp_file");
}
void delete_a_line_code() //刪除一行程式碼
{
char temp1[20], temp2[20]; // 分別為資料夾名稱 檔名稱
printf("請輸入你要操作的檔案所在的資料夾名稱:");
gets(temp1);
int i = search_wenjianjia(temp1); //搜尋並判斷資料夾是否存在
if (i == -1)
{
printf("輸入的資料夾不存在\n");
return;
}
printf("請輸入你要操作的檔名:");
gets(temp2);
Node *p = search_wenjian(i, temp2); //p為檔案的上一結點
if (p == NULL) //判斷要讀取的檔案是否存在
{
printf("要讀取的檔案不存在\n");
return;
}
int x; // 表示在第幾行刪除程式碼
printf("你要在第幾行刪除程式碼:");
scanf("%d", &x);
getchar();
if (judge_hanghao(p->next->data, x) == 0) //判斷輸入的行號是否正確
{
printf("輸入的行號錯誤\n");
return;
}
FILE *fp1, *fp2; //把一個檔案的東西複製到另一個檔案中
copy_file(p->next->data, "temp_file");
if((fp1=fopen(p->next->data,"w"))==NULL)
{
printf("file cannot be opened\n");
return;
}
if((fp2=fopen("temp_file","r"))==NULL)
{
printf("file cannot be opened\n");
return;
}
char str[256] = {0};
int t = 0; //用來計算行號
while(t < x - 1) //複製x行前面的部分
{
fgets(str, 256, fp2);
fputs(str, fp1);
t++;
}
fgets(str, 256, fp2); //取出要刪除的一行
while (fgets(str, 256, fp2) != NULL) //複製剩下的部分
{
fputs(str, fp1);
}
fclose(fp1);
fclose(fp2);
remove("temp_file");
}
void change_a_line_code() //修改一行程式碼
{
char temp1[20], temp2[20]; // 分別為資料夾名稱 檔名稱
printf("請輸入你要操作的檔案所在的資料夾名稱:");
gets(temp1);
int i = search_wenjianjia(temp1); //搜尋並判斷資料夾是否存在
if (i == -1)
{
printf("輸入的資料夾不存在\n");
return;
}
printf("請輸入你要操作的檔名:");
gets(temp2);
Node *p = search_wenjian(i, temp2); //p為檔案的上一結點
if (p == NULL) //判斷要讀取的檔案是否存在
{
printf("要讀取的檔案不存在\n");
return;
}
int x; // 表示在第幾行修改程式碼
printf("你要在第幾行修改程式碼:");
scanf("%d", &x);
getchar();
if (judge_hanghao(p->next->data, x) == 0) //判斷輸入的行號是否正確
{
printf("輸入的行號錯誤\n");
return;
}
char temp3[100]; //存放要修改的程式碼
printf("請輸入你想修改成的一行程式碼:");
gets(temp3);
FILE *fp1, *fp2; //把一個檔案的東西複製到另一個檔案中
copy_file(p->next->data, "temp_file");
if((fp1=fopen(p->next->data,"w"))==NULL)
{
printf("file cannot be opened\n");
return;
}
if((fp2=fopen("temp_file","r"))==NULL)
{
printf("file cannot be opened\n");
return;
}
char str[256] = {0};
int t = 0; //用來計算行號
while(t < x - 1) //複製x行前面的部分
{
fgets(str, 256, fp2);
fputs(str, fp1);
t++;
}
fputs(temp3, fp1); //輸入修改的一行
fputs("\n", fp1);
fgets(str, 256, fp2); //取出原來的這一行
while (fgets(str, 256, fp2) != NULL) //複製剩下的部分
{
fputs(str, fp1);
}
fclose(fp1);
fclose(fp2);
remove("temp_file");
}
void search_code() //按程式碼查詢
{
char temp1[20], temp2[20]; // 分別為資料夾名稱 檔名稱
printf("請輸入你要操作的檔案所在的資料夾名稱:");
gets(temp1);
int i = search_wenjianjia(temp1); //搜尋並判斷資料夾是否存在
if (i == -1)
{
printf("輸入的資料夾不存在\n");
return;
}
printf("請輸入你要操作的檔名:");
gets(temp2);
Node *p = search_wenjian(i, temp2); //p為檔案的上一結點
if (p == NULL) //判斷要讀取的檔案是否存在
{
printf("要讀取的檔案不存在\n");
return;
}
char temp3[100]; //存放要查詢的程式碼
printf("請輸入你要查詢的一行程式碼:");
gets(temp3);
FILE *fp1;
if((fp1=fopen(p->next->data,"r"))==NULL)
{
printf("file cannot be opened\n");
return;
}
int j = 0,len1, len2;
len1 = strlen(temp3); // len1為要查詢的程式碼的長度
char str[256] = {0};
printf("查詢到的結果為:\n");
int s = 0, t = 1; //s用來判斷是否查詢到該程式碼,t用來計錄行數
while(fgets(str, 256, fp1)) //依次取出一行搜尋
{
i = 0; j = 0;
len2 = strlen(str); //len2為取出的一行程式碼的長度
for (; i < len2; )
{
if (str[i] == temp3[j])
{
i++;
j++;
}
if (j == len1)
{
s = 1;
printf("第%d行:%s", t, str);
break;
}
if (str[i] != temp3[j])
{
i++;
j = 0;
}
}
t++;
}
if (s == 0)
printf("未查詢到該程式碼\n");
fclose(fp1);
}
void search_biaohao() //按標號查詢
{
char temp1[20], temp2[20]; // 分別為資料夾名稱 檔名稱
printf("請輸入你要操作的檔案所在的資料夾名稱:");
gets(temp1);
int i = search_wenjianjia(temp1); //搜尋並判斷資料夾是否存在
if (i == -1)
{
printf("輸入的資料夾不存在\n");
return;
}
printf("請輸入你要操作的檔名:");
gets(temp2);
Node *p = search_wenjian(i, temp2); //p為檔案的上一結點
if (p == NULL) //判斷要讀取的檔案是否存在
{
printf("要讀取的檔案不存在\n");
return;
}
printf("請輸入你要查詢的標號:"); //即查詢第幾行
int x;
scanf("%d", &x);
getchar();
FILE *fp1;
if((fp1=fopen(p->next->data,"r"))==NULL)
{
printf("file cannot be opened\n");
return;
}
int t = 1, s = 0; //s用來判斷是否查詢到該程式碼,t用來計錄行數
char str[256] = {0};
printf("查詢結果為:\n");
while (fgets(str, 256, fp1) != NULL) //按標號查詢
{
if (x == t)
{
s = 1;
printf("第%d行:%s", t, str);
break;
}
t++;
}
if (s == 0)
printf("輸入的標號錯誤,未查到結果\n");
fclose(fp1);
}
void neirongcaozuo() //對檔案內容操作選擇
{
while (1)
{
printf("\n請輸入你要進行的操作:");
int ch;
scanf("%d",&ch);
getchar();
switch (ch)
{
case 1: //讀取程式碼資訊
{
read_file();
break;
}
case 2: //增加一行程式碼
{
add_a_line_code();
break;
}
case 3: //刪除一行程式碼
{
delete_a_line_code();
break;
}
case 4: //修改一行程式碼
{
change_a_line_code();
break;
}
case 5: //按程式碼查詢
{
search_code();
break;
}
case 6: //按標號查詢
{
search_biaohao();
break;
}
case 0: //返回上層操作
{
printf("\n");
caidan2();
return;
}
default:
{
printf("輸入有誤,請重新輸入\n");
break;
}
}
}
}
int wenjiancaozuo() //對檔案操作選擇
{
while (1)
{
printf("\n請輸入你要進行的操作:");
int ch;
scanf("%d",&ch);
getchar();
switch (ch)
{
case 1: //建立檔案
{
create_file();
break;
}
case 2: //刪除檔案
{
delete_file();
break;
}
case 3: //顯示某資料夾中的檔案
{
show_file();
break;
}
case 4: //對檔案內容進行操作
{
caidan3();
neirongcaozuo();
break;
}
case 0: //返回上層操作
{
printf("\n");
caidan1();
return ;
}
default:
{
printf("輸入有誤,請重新輸入\n");
break;
}
}
}
}
void wenjianjiacaozuo() //對資料夾操作
{
caidan1(); //輸出選擇選單
int ch;
while (1)
{
printf("\n請輸入你要進行的操作:");
scanf("%d",&ch);
getchar();
switch (ch)
{
case 1: //建立資料夾
{
create_folio();
break;
}
case 2: //檢視資料夾
{
look_folio();
break;
}
case 3: //刪除資料夾
{
delete_folio();
break;
}
case 4: //對檔案操作
{
caidan2();
wenjiancaozuo();
break;
}
case 0: //退出程式
return;
default:
{
printf("輸入有誤,請重新輸入\n");
break;
}
}
}
}
int main()
{
wenjianjiacaozuo();
return 0;
}