题目描述
已知一个ASCII码文件,文件名为dict.dic,该文件中只包含ASCII码中的字符,即可对应整数0—127。我们将ASCII码中的字符分为4类,第一类为大写字母“A—Z”、第二类为小写字母“a—z”、第三类为数字字符“0—9”、第四类为其他字符“!@#$%^&*” 等等(不属于前三类的字符即为第四类)。
要求:
1.统计出这四类字符在该文件中的数量。
2.统计出该文件的行数、行最大长度、行最小长度。这里要注意,虽然文件的换行符确实为一个字符,ASCII码为10,但在统计行长度时,文件中的换行符并不统计在内。
3.输出具体的大小写字母的统计信息,每行一个字母。
4.处理完成后,关闭文件。
内容提示:在本题对文件的操作内容中,会用到三个新的C语言文件操作函数,一种新的打开文件的方式,如下:
1.FILE *fp=fopen(“file.txt”,“r”);//fp即为文件指针,"file.txt"为待打开的文件名,此时应与该程序在一个目录下,"r"为以只读方式打开ASCII码文件。
2.int ch=fgetc(fp);//从fp指向的文件中读取一个字节(字符),存入变量ch内。
3.fclose(fp);//关闭fp指向的文件。
输入
只可能是1,2,3三个整数之一,其输出分别对应输出中的Task1,Task2,Task3。
输出
如果dict.dic文件内容如下: (文件每行都有换行符,且前边无空格)
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
~!@#$%^&*()_+`1234567890- =][’;/.,<>?":{}|
则三个任务的输出分别如下: (注意:Task1、2、3等也需要输出)
Task1:
capital: 26
lowercase: 26
digit: 10
others: 36
Task2:
line: 3
43 characters in max line.
26 characters in min line.
Task3:
CAPITAL:
A:1
B:1
C:1
D:1
E:1
F:1
G:1
H:1
I:1
J:1
K:1
L:1
M:1
N:1
O:1
P:1
Q:1
R:1
S:1
T:1
U:1
V:1
W:1
X:1
Y:1
Z:1
LOWERCASE:
a:1
b:1
c:1
d:1
e:1
f:1
g:1
h:1
i:1
j:1
k:1
l:1
m:1
n:1
o:1
p:1
q:1
r:1
s:1
t:1
u:1
v:1
w:1
x:1
y:1
z:1
源代码
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int count;
struct node * nextPtr;
}LISTNODE, * LISTNODEPTR;
void createListHead(LISTNODEPTR * ,LISTNODEPTR *);
void insertEnd(int,LISTNODEPTR *);
void countPlus(int,LISTNODEPTR);
void printList(LISTNODEPTR,int);
void destroyList(LISTNODEPTR headPtr);
int main(){
FILE * fp = fopen("dict.dic","r");
LISTNODEPTR capitalHeadPtr,capitalLastPtr,lowercaseHeadPtr,lowercaseLastPtr;
createListHead(&capitalHeadPtr,&capitalLastPtr);
createListHead(&lowercaseHeadPtr,&lowercaseLastPtr);
int letter = 26;
while(letter--){
insertEnd(0,&capitalLastPtr);
insertEnd(0,&lowercaseLastPtr);
}
int mode;
scanf("%d",&mode);
int ch = fgetc(fp);
int capitalCount = 0,lowercaseCount = 0,digitCount = 0,othersCount = 0,lineCount = 0,lineMax,lineMin,flag = 0,temp;
while(ch != EOF){
if(ch != '\n'){
lineCount++;
if(ch >= 'A' && ch <= 'Z') {
capitalCount++;
countPlus(ch-'A'+1,capitalHeadPtr);
}
else if(ch >= 'a' && ch <= 'z') {
lowercaseCount++;
countPlus(ch-'a'+1,lowercaseHeadPtr);
}
else if(ch >= '0' && ch <= '9') digitCount++;
else othersCount++;
}
else{
flag++;
othersCount++;
if(flag == 1){
lineMax = lineCount;
lineMin = lineCount;
}
else if(lineCount > lineMax) lineMax = lineCount;
else if(lineCount < lineMin) lineMin = lineCount;
lineCount = 0;
}
temp = ch;
ch = fgetc(fp);
}
if(temp != '\n'){
flag++;
othersCount++;
if(flag == 1){
lineMax = lineCount;
lineMin = lineCount;
}
else if(lineCount > lineMax) lineMax = lineCount;
else if(lineCount < lineMin) lineMin = lineCount;
lineCount = 0;
ch = fgetc(fp);
}
switch (mode)
{
case 1:
printf("Task1:\ncapital: %d\nlowercase: %d\ndigit: %d\nothers: %d\n",capitalCount,lowercaseCount,digitCount,othersCount);
break;
case 2:
printf("Task2:\nline: %d\n%d characters in max line.\n%d characters in min line.",flag,lineMax,lineMin);
break;
case 3:
printf("Task3:\nCAPITAL:\n");
printList(capitalHeadPtr,1);
printf("LOWERCASE:\n");
printList(lowercaseHeadPtr,0);
break;
default:
printf("??");
break;
}
destroyList(capitalHeadPtr);
destroyList(lowercaseHeadPtr);
fclose(fp);
return 0;
}
void createListHead(LISTNODEPTR * headPtrPtr,LISTNODEPTR * lastPtrPtr){
(*headPtrPtr) = malloc(sizeof(LISTNODE));
if((*headPtrPtr) != NULL){
(*headPtrPtr)->nextPtr = NULL;
(*lastPtrPtr) = (*headPtrPtr);
}
else{
printf("Error! -101");
}
}
void insertEnd(int data,LISTNODEPTR * lastPtrPtr){
LISTNODEPTR newPtr = malloc(sizeof(LISTNODE));
if(newPtr != NULL){
newPtr->count = data;
newPtr->nextPtr = NULL;
(*lastPtrPtr)->nextPtr = newPtr;
(*lastPtrPtr) = newPtr;
}
else{
printf("Error! -102");
}
}
void countPlus(int num,LISTNODEPTR headPtr){
while(num--){
headPtr = headPtr->nextPtr;
}
(headPtr->count)++;
}
void printList(LISTNODEPTR headPtr,int mode){
int num = 0;
while (headPtr->nextPtr != NULL)
{
headPtr = headPtr->nextPtr;
if(mode){
printf("%c:%d\n",'A'+num,headPtr->count);
}
else{
printf("%c:%d\n",'a'+num,headPtr->count);
}
num++;
}
}
void destroyList(LISTNODEPTR headPtr){
LISTNODEPTR tempPtr = NULL;
while(headPtr != NULL){
tempPtr = headPtr;
headPtr = headPtr->nextPtr;
free(tempPtr);
}
}
整体思路
其实挺无脑的,题目让你干啥你就干啥的类型。。。存放大小写数据用的链表,用数组貌似会更简单。。。
注意事项
最后一行只有文件结束符(EOF)时不能把它看作一行!!要特殊处理