【反思總結】
1.補充學習帶參數的main函數知識
2.學習不帶頭結點的循環單連結清單的建立
易錯點:不帶頭結點的循環單連結清單建立要先讀入資料,再用尾插法插入結點
3.逆序列印不帶頭結點的單連結清單(易錯點:要傳入兩個指針,一個用作循環條件判斷,一個作為循環變量進行遞歸)
【代碼】
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <string.h>
#define maxSize 100
#define N 3
typedef struct LNode
{
char data[maxSize];
struct LNode* next;
}LNode;
int PrintReverse(LNode* L,LNode* r, int n)//此處n不能命名為N,否則會産生命名沖突
{
if (r->next == L)
{
printf("倒數第%d行:%s\n", 1, r->data);
return 1;//列印倒數第一行傳回1
}
else
{
int i;
i = PrintReverse(L, r->next, n) + 1;//i表示目前是倒數第i行
if (i <= n)
{
printf("倒數第%d行:%s", i, r->data);
}
return i;
}
}
int JudgeMistakes(char* num, char *filename, int *n)
{
int i;
i = atoi(num);
//檢查n是否正确
if (i < 0)
{
i = i * -1;
*n = i;
}
else
{
return 0;
}
//檢查檔案名是否正确
/*略*/
return 1;
}
void tail(int n, char* filename)
{
LNode* L = (LNode*)malloc(sizeof(LNode));
L->next = L;
LNode* r = L;
int count;
count = 0;
LNode* s = NULL;
FILE* fp;
if((fp=fopen(filename,"r"))==NULL)
return;
char str[maxSize];
fgets(str, N, fp);
strcpy(L->data, str);//易錯點:不帶頭結點的循環單連結清單建立要先讀入資料,再用尾插法插入結點
while (fgets(str, N, fp) != NULL)
{
s = (LNode*)malloc(sizeof(LNode));
strcpy(s->data, str);
s->next = r->next;
r->next = s;
r = s;
}
PrintReverse(L, L, n);
}
int main(int argc, char* argv[])//argv是字元指針數組,每一個指針都指向一個字元串
{
int num;
//argv[0]是指令名此處用Project1代替 tail,argv[1]是讀取的最後行數,argv[2]是檔案名
if (JudgeMistakes(argv[1], argv[2], &num) == 0)
{
printf("Wrong");
return 0;
}
tail(num, argv[2]);
return 0;
}
【運作結果】
【檔案】
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z