问题 A: 实验12_1_初识ASCII码文件
时间限制: 1 Sec 内存限制: 128 MB
题目描述
已知一个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
样例输入
1
样例输出
Task1: capital: 26 lowercase: 26 digit: 10 others: 36
#include <stdio.h>
void TaskOne(){
FILE *fPtr;
fPtr = fopen("dict.dic","r");
int currentSign;
int digit = 0,capital = 0,lowercase = 0,others = 0;
currentSign = fgetc(fPtr);
while (currentSign != EOF){
if (currentSign >= '0'&¤tSign <= '9'){
digit++;
} else if (currentSign >= 'A'&¤tSign <= 'Z'){
capital++;
} else if (currentSign >= 'a'&¤tSign <= 'z') {
lowercase++;
} else {
others++;
}
currentSign = fgetc(fPtr);
}
printf("Task1:\n");
printf("capital: %d\n",capital);
printf("lowercase: %d\n",lowercase);
printf("digit: %d\n",digit);
printf("others: %d\n",others);
fclose(fPtr);
}
void TaskTwo(){
FILE *fPtr;
fPtr = fopen("dict.dic","r");
int currentSign,lenOfCurLine = 0,lenMax = 0,lenMin = 999999,lineNumber = 0;
currentSign = fgetc(fPtr);
while (currentSign != EOF){
while (currentSign != '\n'&¤tSign != EOF){//请注意EOF是不需要单引号的
lenOfCurLine++;
currentSign = fgetc(fPtr);
}
lineNumber++;
if (lenOfCurLine > lenMax){
lenMax = lenOfCurLine;
}
if (lenOfCurLine < lenMin){
lenMin = lenOfCurLine;
}
if (currentSign == 10) {
currentSign = fgetc(fPtr);
lenOfCurLine = 0;
} else {
continue;
}
}
printf("Task2:\n");
printf("line: %d\n",lineNumber);
printf("%d characters in max line.\n",lenMax);
printf("%d characters in min line.\n",lenMin);
fclose(fPtr);
}
void TaskThree(){
FILE *fPtr;
int currentSign,capital[30]={0},lowercase[30]={0};
fPtr = fopen("dict.dic","r");
currentSign = fgetc(fPtr);
while (currentSign != EOF){
if (currentSign >= 'A'&¤tSign <= 'Z'){
capital[currentSign-'A']++;
}
if (currentSign >= 'a'&¤tSign <= 'z') {
lowercase[currentSign-'a']++;
}
currentSign = fgetc(fPtr);
}
printf("Task3:\n");
printf("CAPITAL:\n");
for (char i = 'A'; i <= 'Z'; ++i) {
printf("%c:%d\n",i,capital[i-'A']);
}
printf("LOWERCASE:\n");
for (char i = 'a'; i <= 'z'; ++i) {
printf("%c:%d\n",i,lowercase[i-'a']);
}
//another correct version
// printf("Task3:\nCAPITAL:\n");
// for(int i=0;i<26;i++){
// printf("%c:%d\n",'A'+i,capital[i]);
// }
// printf("LOWERCASE:\n");
// for(int i=0;i<26;i++){
// printf("%c:%d\n",'a'+i,lowercase[i]);
// }
fclose(fPtr);
}
int main() {
int taskID;
scanf("%d",&taskID);
switch (taskID) {
case 1:TaskOne();break;
case 2:TaskTwo();break;
case 3:TaskThree();break;
default: ;
}
return 0;
}
问题 B: 实验12_6_初识二进制文件
时间限制: 1 Sec 内存限制: 128 MB
题目描述
常用的数据类型有字符型(char 型)、短整型(short 型)、整型(int 型)、长整型(long 型)、拓展长整型(long long 型)、单精度浮点型(float 型)、双精度浮点型(double 型)。问题围绕着数据类型与二进制文件展开。现有一个二进制文件,文件名为dict.dic,生成这个文件的C语言代码大概是这样的:
变量如下:
char a,aa[5];//注意这里数组aa为正常使用的字符串,所以会包含字符'\0',它不需要输出
short b,bb[5];
int c,cc[5];
long d,dd[5];
long long e,ee[5];
float g,gg[5];
double h,hh[5];
int i ;
写入的代码段是这样:
fwrite(&a,sizeof(a),1,fp);
fwrite(&b,sizeof(b),1,fp);
fwrite(&c,sizeof(c),1,fp);
fwrite(&d,sizeof(d),1,fp);
fwrite(&e,sizeof(e),1,fp);
fwrite(&g,sizeof(g),1,fp);
fwrite(&h,sizeof(h),1,fp);
fwrite(aa,sizeof(a),5,fp);
fwrite(bb,sizeof(b),5,fp);
fwrite(cc,sizeof(c),5,fp);
fwrite(dd,sizeof(d),5,fp);
fwrite(ee,sizeof(e),5,fp);
fwrite(gg,sizeof(g),5,fp);
fwrite(hh,sizeof(h),5,fp);
这个代码段被连续执行了5次。当然每次写入的数据是不同的。
你的任务是从dict.dic中按照输入的顺序,读出7种单独变量,分别存到对应类型的变量中,假设为a、b、c、d、e、g、h。再从该文件中读出7个长度为5的数组,分别存到aa[5]、bb[5]、cc[5]、dd[5]、ee[5]、gg[5]、hh[5]中。最后将它们的值全部输出到屏幕上。
注意,所有变量均不会超过其存储范围。
内容提示:在本题对文件的操作内容中,会用到C语言文件操作函数,其打开文件的方式,如下:
1.FILE *fp=fopen("file.dat","rb");//"rb"为以只读方式打开二进制文件。
2.fread的样例代码:
#include<stdio.h>
int main()
{
int c,cc[5]={0};
FILE *fp=fopen("file.dat","rb");
fread(&c,sizeof(int),1,fp); //从fp指向的文件中读出一个整型变量
fread(cc,sizeof(int),5,fp); //从fp指向的文件中读出一个长度为5的整型数组。
fclose(fp);
return 0;
}
输入
为一个整数,只可能是1,2,3,4,5之一。
输出
将dict.dic中的相关内容输出到屏幕上,如果输入是1,则输出那段代码第一次写入的内容,如果输入是2,则输出那段代码第二次写入的内容,依此类推。
形式如样例。
样例输入
1
样例输出
X 1234 2000000000 2000000000 500000000000000 1.234500 9.876543 XXX 1234 1234 1234 1234 1234 2000000000 2000000000 2000000000 2000000000 2000000000 2000000000 2000000000 2000000000 2000000000 2000000000 500000000000000 500000000000000 500000000000000 500000000000000 500000000000000 1.234500 1.234500 1.234500 1.234500 1.234500 9.876543 9.876543 9.876543 9.876543 9.876543
#include <stdio.h>
int main() {
FILE * fPtr;
fPtr = fopen("dict.dic","rb");
char cr,string[5];//注意这里数组aa为正常使用的字符串,所以会包含字符'\0',它不需要输出
short st,stArray[5];
int it,itArray[5];
long lg,lgArray[5];
long long llg,llArray[5];
float ft,ftArray[5];
double de,deArray[5];
int num;
scanf("%d",&num);
for (int times = 0; times < num; ++times) {
fread(&cr,sizeof (char ),1,fPtr);
fread(&st,sizeof(short ),1,fPtr);
fread(&it,sizeof(int ),1,fPtr);
fread(&lg,sizeof(long ),1,fPtr);
fread(&llg,sizeof(long long ),1,fPtr);
fread(&ft,sizeof(float ),1,fPtr);
fread(&de,sizeof(double ),1,fPtr);
fread(string,sizeof(char ),5,fPtr);
fread(stArray,sizeof(short ),5,fPtr);
fread(itArray,sizeof(int ),5,fPtr);
fread(lgArray,sizeof(long ),5,fPtr);
fread(llArray,sizeof(long long ),5,fPtr);
fread(ftArray,sizeof(float ),5,fPtr);
fread(deArray,sizeof(double ),5,fPtr);
}
printf("%c\n%hd\n%d\n%ld\n%lld\n%f\n%lf\n%s\n",cr,st,it,lg,llg,ft,de,string);
for (int position = 0; position < 4; ++position) {
printf("%hd ",stArray[position]);
}
printf("%hd\n",stArray[4]);
for (int position = 0; position < 4; ++position) {
printf("%d ",itArray[position]);
}
printf("%d\n",itArray[4]);
for (int position = 0; position < 4; ++position) {
printf("%ld ",lgArray[position]);
}
printf("%ld\n",lgArray[4]);
for (int position = 0; position < 4; ++position) {
printf("%lld ",llArray[position]);
}
printf("%lld\n",llArray[4]);
for (int position = 0; position < 4; ++position) {
printf("%f ",ftArray[position]);
}
printf("%f\n",ftArray[4]);
for (int position = 0; position < 4; ++position) {
printf("%lf ",deArray[position]);
}
printf("%lf\n",deArray[4]);
fclose(fPtr);
return 0;
}
问题 C: 实验12_4_过滤注释
时间限制: 1 Sec 内存限制: 128 MB
题目描述
C语言的注释分为两种,第一种:在一行源代码中“//”后的内容为注释内容。第二种:“/*”与“*/”之间的内容为注释内容。第三种:程序中只出现了“/*”,没有“*/”与之对应,那么将“/*”后的全部内容都要过滤掉。注意,只要是注释内容,那么注释内容中的字符应该全部忽略,即不起任何的作用。例如“/*”与“*/”之间如果再有“//”,那么“//”不应起作用;如果“//”再有“/*”,那么“/*”也不应起作用。
你的任务是先打开一个名字为dict.dic的文本文件,该文件中前5行每行为1个整数,从第6行开始为5段C语言的源代码。那5个数字代表这5段源代码结束的行数,比如如果第一行的整数为20,第二行的整数为60,则表示从第6行到第20为第一段代码,从第21行到第60为第二段代码。然后根据输入要求将源代码中所有注释过滤掉。
在本过滤注释系统中,你可以忽略源文件中双引号导致“//”、“/*”、“*/”失去作用的情况,即只要“//”、“/*”、“*/”不是注释内容,在任何情况下都起作用。
输入
只可能是1,2,3,4,5之一
输出
输入为1则输出第一段代码过滤后的结果,输入为2则输出第二段代码过滤后的结果,依此类推。
样例输入
1
样例输出
如果第一段代码是这样: /* @Author: BUPT @Date: 2010 8 26 */ #include<stdio.h> int main() { int a = 10 , b = 2 , c ; c = a / b ; //I just want to test '/' printf("I love programming C.\n") ; //"printf" is a useful function /* printf("I hope you love it too!\n") ; /* //C is not always hard , if you love it , it will not treat you rough. */ return 0 ; } 则输出是这样: #include<stdio.h> int main() { int a = 10 , b = 2 , c ; c = a / b ; printf("I love programming C.\n") ; printf("I hope you love it too!\n") ; return 0 ; }
#include <stdio.h>
int main()
{
FILE* fp;
char ch = '\0', ch1 = '\0', ch2 = '\0';
int Part[6] = { 0 }, targetPart = 0,lines ,readedLines = 0;
Part[0] = 5;
scanf("%d", &targetPart);
fp=fopen("dict.dic", "r");
fscanf(fp, "%d\n%d\n%d\n%d\n%d\n", Part + 1, Part + 2, Part + 3, Part + 4, Part + 5);
lines = Part[targetPart]-Part[targetPart-1];
if (targetPart != 1){
char tem[99999];
for (int j = 0; j < Part[targetPart-1]-5; ++j) {
fgets(tem,99998,fp);
}
}
while (ch != EOF&&readedLines < lines)
{
ch = fgetc(fp);
if (feof(fp))
return 0;
if (ch == '/')
{
ch1 = ch;
ch2 = fgetc(fp);
if ( ch2 == '*')
{//ch1--ch1;ch2--ch;ch--ch2;
while (!feof(fp))
{
ch2 = fgetc(fp);
if (ch1 == '*' && ch2 == '/')
{
ch1 = '\0';
ch2 = '\0';
ch = ch2;
break;
}
ch1 = ch2;
if (ch2 == '\n')
{
readedLines++;
}
if (readedLines > lines)
return 0;
}
}
else if ( ch2 == '/')
{
while (!feof(fp))
{
ch = fgetc(fp);
if (ch == '\n')
{
ch = '\0';
ch1 = '\0';
ch2 = '\0';
readedLines++;
printf("\n");
break;
}
}
}
else
{
printf("%c%c", ch1, ch2);
}
}
else
{
printf("%c", ch);
}
if (ch == '\n' || feof(fp) == -1)
readedLines++;
}
fclose(fp);
return 0;
}
问题 D: 实验12_A_和谐词汇
时间限制: 1 Sec 内存限制: 128 MB
题目描述
互联网中存在许多的不和谐词汇,在我们浏览互联网的时候,搜索引擎经常会出现提示信息“根据相关法律法规和政策,部分搜索结果未予显示”。小王同学也想制作一个自己的屏蔽词库,这样他就可以将自己不喜欢的词汇从文件中换成别的字符了。屏蔽词库是一个ASCII码文件,这个文件中只含有单词,每个单词占一行,每个单词中只可能有大小写字母与空格。题目中和谐词库的文件名为dict.dic。(屏蔽词库中每个词汇长度小于10,屏蔽词汇个数不超过10.)
你的任务是将输入中的所有和谐词库中的词语全部替换成“!@#$%^&*”(按住键盘shift和数字1至8),然后输出。这里要注意,如果一个词语中包含屏蔽词汇,那么只将屏蔽词汇替换,例如“hehasAAA”被处理后将得到“he!@#$%^&*AAA”,注意屏蔽词汇区分大小写,即aaa与AAA是两个不同的单词,为了使问题简化,屏蔽词汇中不会出现互相包含的情况,如“xabcx”与“abc”不会同时出现在同一个屏蔽词库中。由于小王同学很不擅长文件操作,所以他希望你能帮他制作这个屏蔽词汇程序。
输入
若干长度小于110的字符串。
输出
添加屏蔽词后的结果。
样例输入
The night falls gently. And you are not here. I missing you more and more and I start getting worried as I stare at the door just waiting for you to surprise me with your arrival at any moment. Sweet delusion... you are so far away right now that all I can ask for is that time moves faster...
样例输出
如果屏蔽词库如下:(文件中每行都有换行符) is good are the ha ha some get has more bad 则输出: The night falls gently. And you !@#$%^&* not here. I m!@#$%^&*sing you !@#$%^&* and !@#$%^&* and I start !@#$%^&*ting worried as I st!@#$%^&* at !@#$%^&* door just waiting for you to surpr!@#$%^&*e me with your arrival at any moment. Sweet delusion... you !@#$%^&* so far away right now that all I can ask for !@#$%^&* that time moves faster...x
//Multi-Function Version
#include "stdio.h"
int GetWords(char a[][15] , FILE *fp)
{
int num , j;
int ch , line = 0;
ch = fgetc(fp);
for(int i = 0 ; ch != EOF ; i++)
{
num = 0;
line++;
for(j = 0 ; ch != 10 && ch != EOF ; j++)
{
a[i][j] = (char)ch;
//num++;
ch = fgetc(fp);
}
ch = fgetc(fp);
a[i][j] = '\0';
}
return line;
}
void ShieldWords(char a[][15] ,int line)
{
char Replace[8] = {"!@#$%^&*"};
char words[150];
int i , j , k , flag , mid;
while(gets(words))//逐个字符串处理
{
i = 0;
while(words[i] != '\0')//一个字符串的逐个元素查找
{
flag = 0;
for(j = 0 ; j < line ; j++)//每个元素和所有敏感词的首字母依次比对
{
k = 0;
mid = i;
while(words[mid] == a[j][k])//首字母对应了,再依次向后比对
{
mid++;
k++;
if(a[j][k] == '\0')
{
for(int m = 0 ; m < 8 ; m++)
printf("%c",Replace[m]);
flag = 1;
break;
}
}
if(flag)
break;
}
if(flag)
{
i = mid;
}else
{
printf("%c",words[i]);
i++;
}
}
printf("\n");
}
}
int main()
{
FILE *fp;
fp = fopen("E:\\Clion\\project\\homework\\second\\dict.txt" , "r");
char a[15][15] = {0};
int line;
line = GetWords(a , fp);
ShieldWords(a , line);
fclose(fp);
return 0;
}
//One Function Version
#include <stdio.h>
#include <string.h>
int main() {
//初始化
FILE *fPtr = fopen("dict.dic","r");
char harmonyWords[11][11] ={0};
int numbersOfHarmonyWords = 0;
//读入需要被和谐的词汇们
char inputTemp[11] = {0};
fgets(inputTemp,11,fPtr);
for (int i = 0; i < 10&&inputTemp[0] != EOF; ++i) {
strcpy(harmonyWords[i],inputTemp);
numbersOfHarmonyWords++;
for (int j = 0; j < 11; ++j) {
inputTemp[i] = 0;
}
fgets(inputTemp,11,fPtr);
}
//和谐
char checkingString[120],exchange[8] ={"!@#$%^&*"};
int i,j,k,prim,now;
while (gets(checkingString)){//逐个字符串处理
i = 0;//使用i遍历整个字符串
while (checkingString[i] != '\0'){//一个字符串的逐个元素查找
prim = 0;
for ( j = 0; j < numbersOfHarmonyWords; ++j) {//每个元素和所有敏感词的首字母依次比对
k = 0;//统计本次和谐了多少个字符
now = i;
while (checkingString[now] == harmonyWords[j][k]){//首字母对应了,再依次向后比对
now++;
k++;
if (harmonyWords[j][k] == '\n'){
for (int l = 0; l < 8; ++l) {
printf("%c",exchange[l]);
}
prim = 1;
break;
}
}
if (prim == 1){
break;
}
}
if (prim == 1){
i = now;
} else {
printf("%c",checkingString[i]);
i++;
}
}
printf("\n");
}
fclose(fPtr);
return 0;
}