13.11编程练习

1.修改程序清单13.1中的程序,使之不采用命令行参数,而是请求用户输入文件名并读入用户的响应。

<span style="font-family:System;">#include <stdio.h>
#include <stdlib.h>
#define SIZE 100
int main(void)
{
	int ch;
	FILE *fp;
	int count=0;
	char str[SIZE];
	printf("Please enter filename.\n");
	gets(str);
	if((fp=fopen(str,"r"))==NULL)
	{
		printf("Can't open %s\n",str);
		exit(1);
	}
	while((ch=getc(fp))!=EOF)
	{
		putc(ch,stdout);
		count++;
	}
	printf("\n");
	fclose(fp);
	printf("File %s has %d characters\n",str,count);
	return 0;
	
}</span>
2.编写一个文件复制程序。程序需要从命令行获得源文件和目的文件名。尽可能使用标准I/O和二进制模式。

<span style="font-family:System;">#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
	int ch;
	FILE *fp,*target;

	
	if(argc!=3)
	{
		printf("Usage: %s filename\n",argv[0]);
		exit(1);
	}
	if((fp=fopen(argv[1],"rb"))==NULL)
	{
		printf("Can't open %s\n",argv[1]);
		exit(1);
	}
	if((target=fopen(argv[2],"wb"))==NULL)
	{
		printf("Can't open %s\n",argv[2]);
		exit(1);
	}	
	while((ch=getc(fp))!=EOF)
	{
		putc(ch,target);
	}
	if(fclose(fp)!=0)
		fprintf(stderr,"Error in closing files 1\n");
	
	if(fclose(target)!=0)
		fprintf(stderr,"Error in closing files 2\n");	

	return 0;
	
}</span>
3.编写一个文件复制程序,提示用户输入原文件名和输出文件名。在想输出文件写入时,程序应当使用ctype.h中定义的toupper()函数将所有的文本转换成大写。使用标准I/O和文本模式。

<span style="font-family:System;">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define LEN 40
int main(int argc,char *argv[])
{
	FILE *fp1,*fp2;
	int ch;
	char fileName[2][LEN];

	const char *fileForm={".txt"};
	
	printf("Please enter your first file name.\n");
	gets(fileName[0]);
	strcat(fileName[0],fileForm);
	
	printf("You'll enter characters to %s file\n",fileName[0]);
	fp1=fopen(fileName[0],"w");
	while((ch=getchar())!=EOF)
	{
		putc(ch,fp1);
	}
	//关闭以保存文件1中的内容,否则不会保存。 再打开时为了文件2读取并复制 
	fclose(fp1);
	fp1=fopen(fileName[0],"r");
	

	printf("Please enter your second file name.and I will copy first file into it\n");
	gets(fileName[1]);
	strcat(fileName[1],fileForm);
	fp2=fopen(fileName[1],"w");	
	
	while((ch=getc(fp1))!=EOF)
	{
		putc(toupper(ch),fp2);
	}
	
	if(fclose(fp1)!=0)
		fprintf(stderr,"Error in closing files 1\n");
	
	if(fclose(fp2)!=0)
		fprintf(stderr,"Error in closing files 2\n");	
	return 0;
}</span>
4.编写一段程序,一次在屏幕上显示命令行中列出的所有文件。使用argc控制循环。

<span style="font-family:System;">#include <stdio.h>
#include <stdlib.h>
void OpenFile(char *argv[],FILE *fp[],int argc);
void ShowFile(char *argv[],FILE *fp[],int argc);
void CloseFile(char *argv[],FILE *fp[],int argc);
/*本程序只读取3个文件,文件需要事先建立,并且写入数据*/
int main(int argc,char *argv[])
{
	int ch;
	FILE *fp[3];//指向文件指针的数组 
	OpenFile(argv,fp,argc); 
	ShowFile(argv,fp,argc);
	CloseFile(argv,fp,argc);
	return 0;	
}
void OpenFile(char *argv[],FILE *fp[],int argc)
{
	int i;
	for(i=1;i<argc;i++)
	{
		if((fp[i-1]=fopen(argv[i],"r"))==NULL)
		{
			fprintf(stderr,"Error to open %s file",argv[i]);	
			exit(1);		
		}
		
	}

}

void ShowFile(char *argv[],FILE *fp[],int argc)
{
	int i;
	int ch;
	for(i=1;i<argc;i++)
	{
		printf("%s file:\n",argv[i]);
		while((ch=getc(fp[i-1]))!=EOF)
		{
			putc(ch,stdout);
		}
		printf("\n");
	}
}
void CloseFile(char *argv[],FILE *fp[],int argc)
{
	int i;
	for(i=1;i<argc;i++)
	{
		if(fclose(fp[i-1])!=0)
		{
			fprintf(stderr,"Error to close %s file",argv[i]);	
			exit(2);		
		}
		
	}

}
</span>
6.使用命令行参数的程序要求用户记住正确的使用方法。重写13.2中的程序,不适用命令行参数,而是提示用户键入所需的信息。

<span style="font-family:System;">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 40
/*本程序需要事先建立一个bbb.txt的源文件并且写入内容,目标文件由程序自动建立*/
int main(void)
{
	FILE *source,*target;
	char name[LEN];
	const char *form=".txt";
	char ch;
	int count=0;
	
	printf("Please enter the name of target file :\n");
	gets(name);
	strcat(name,form);
	if((target=fopen(name,"w"))==NULL)
	{
		fprintf(stderr,"Could not creat/find target file.\n");
		exit(1);
	}
	if((source=fopen("bbb.txt","r"))==NULL)
	{
		fprintf(stderr,"Could not creat/find source file.\n");
		exit(1);
	}
	while((ch=getc(source))!=EOF)
	{
		if(count++%3==0)
		{
			putc(ch,target);
		}
	}
	if(fclose(target)!=0 || fclose(source)!=0)
	{
		fprintf(stderr,"error to close files.\n");
	}
	return 0;
	
}</span>

7.编写一个打开两个文件的程序。可以使用命令行参数或者请求用户输入来获得文件名。

a.让程序打印第一个文件的第一行、第二个文件的第一行、第一个文件的第二行、第一个文件的第二行、第二个文件的第二行、以此类推,直到打印完行数较多的文件的最后一行。

<span style="font-family:System;">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
	FILE *fpa,*fpb;
	int state=0;
	int cha=0,chb=0;
	int i;
	if( (fpa=fopen("a.txt","r"))==NULL )
	{
		fprintf(stderr,"Error to open \"a.txt\".\n");
		exit(1);
	}
	if( (fpb=fopen("b.txt","r"))==NULL )
	{
		fprintf(stderr,"Error to open \"b.txt\".\n");
		exit(1);
	}
	
	while( (cha != EOF) || (chb != EOF))
	{
		if(state==0)
		{
			while((cha=getc(fpa))!='\n' && cha!= EOF)
			{
				putchar(cha);
			}
			state=1;
		}
		if(state==1)
		{
			while((chb=getc(fpb))!='\n' && chb!=EOF)
			{
				putchar(chb);
			}
			state=0;
		}
	}
	
	if( fclose(fpa)!=0 )
	{
		fprintf(stderr,"Error to close \"a.txt\".\n");
		exit(1);
	}
	if( fclose(fpb)!=0 )
	{
		fprintf(stderr,"Error to close \"b.txt\".\n");
		exit(1);
	}
	
	
	return 0;
}
</span>
b.修改程序,把行号相同的行打印到同一行上。

<span style="font-family:System;">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
	FILE *fpa,*fpb;
	int stateN=0;
	int stateEOF=1;
	int cha=0,chb=0;
	int i;
	if( (fpa=fopen("a.txt","r"))==NULL )
	{
		fprintf(stderr,"Error to open \"a.txt\".\n");
		exit(1);
	}
	if( (fpb=fopen("b.txt","r"))==NULL )
	{
		fprintf(stderr,"Error to open \"b.txt\".\n");
		exit(1);
	}
	
	while( (cha != EOF) || (chb != EOF))
	{
		if(stateN==0)
		{
			while((cha=getc(fpa))!='\n' && cha!= EOF)
			{
				putchar(cha);
			}
			stateN=1;
		}
		if(stateN==1)
		{
			while((chb=getc(fpb))!='\n' && chb!=EOF)
			{
				putchar(chb);
			}
			stateN=0;
		}
		printf("\n");
	}
	
	if( fclose(fpa)!=0 )
	{
		fprintf(stderr,"Error to close \"a.txt\".\n");
		exit(1);
	}
	if( fclose(fpb)!=0 )
	{
		fprintf(stderr,"Error to close \"b.txt\".\n");
		exit(1);
	}
	
	
	return 0;
}</span>



8.编写一段程序,将一个字符、零个或多个文件名作为参数命令。如果字符后没有参数跟随,程序读取标准输入文件。否则,程序依次打开每个文件,然后报告每个文件中该字符的出现次数。文件名和字符本身也与计数值一起报告。程序中包括错误检查,以确定参数数目是否正确和是否能打开文件。如果不能打开文件,程序也要报告这一情况然后处理下一文件。
<span style="font-family:System;"><pre name="code" class="cpp">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROW 10
#define COLS 20

int main(int argc,char *argv[])
{

	const char Check='a';	//带查找的字符 
	int count;	//计数 
	int i;
	int ch;
	const char *FileFormat=".txt"; 
	
	if(argc<2)
	{
		fprintf(stderr,"Missing command.\n");
		exit(1);
	}
	else if(argc==2)
	{
		FILE **fp=NULL;
		int FileNum;
		char name[ROW][COLS];
		printf("Please enter how many files do you want to creat:( it must be <=%d)\n",ROW);
		while( scanf("%d",&FileNum)!=1 || FileNum>ROW )
			continue;
		getchar(); 	//读取scanf留下的回车 
		fp=(FILE **)malloc(sizeof(FILE *) * FileNum);	//创建一个存放文件指针的数组 
		
		for(i=0;i<FileNum;i++)
		{
			printf("Plese enter the name of file for file %d:\n",i+1);
			gets(name[i]);
			strcat(name[i],FileFormat);
			if((fp[i]=fopen(name[i],"w")) == NULL)
			{
				fprintf(stderr,"Error to open files %s\n",name[i]);
				break;
			}
			printf("Please enter your character to file %d.\n",i+1);
			count=0;
			while((ch=getc(stdin))!=EOF)
			{
				if(ch==Check)
				{
					count++;
				}
				putc(ch,fp[i]);
			}
			printf("\nThere %d '%c' in %s file\n",count,Check,name[i]);
			
			if( fclose(fp[i])!=0)
			{
				fprintf(stderr,"Error to close %s file\n",name[i]);
				break;
			}
		}
		
		free(fp);
	}
	else	//默认命令行参数中的文件都是已经存在并且写入数据的 
	{
		int j;
		FILE **fp=NULL;
		int FileNum=argc-2;
		fp=(FILE **)malloc(sizeof(FILE *) * FileNum);
		
		for(i=2,j=0;i<argc;i++,j++)
		{
			if( (fp[j]=fopen(argv[i],"r")) == NULL)
			{
				fprintf(stderr,"Error to open %s file",argv[i]);
				break;
			}
			count=0;
			printf("%s file:\n",argv[i]);
			while((ch=getc(fp[j])) != EOF)
			{
				putc(ch,stdout);
				if(ch==Check)
				{
					count++;
				}
			}
			printf("\nThere %d '%c' in %s file\n",count,Check,argv[i]);
			
			if( fclose(fp[j])!=0)
			{
				fprintf(stderr,"Error to close %s file\n",argv[i]);
				break;
			}
			
		}
		free(fp);
	}
	return 0;
}
</span>

 

9.修改程序清单13.3中的程序,从1开始,根据加入列表的顺序为每个单词编号。当再次运行程序的时候,确保新的单词编号接着前面的编号开始。

10.编写一个程序,打开一个文本文件,文件名通过交互方式获得。建立一个循环。请求用户输入一个文件位置。然后程序打印从该位置开始到下一个换行符之间的部分。用户通过输入非数字字符来终止循环。

<span style="font-family:System;">#include <stdio.h>
#include <string.h>
#include <stdlib.h>

 
int main(void)
{

  	FILE *fp;
  	int ch;
  	long byte;
  	
  	puts("Please enter name of file.");
  	gets(name);
  	if((fp=fopen(name,"r")) == NULL)
  	{
  		fprintf(stderr,"Error to open %s file",name);
  		exit(1);
	}
	puts("Please enter which byte do you want to start  printing (q to quit):");
	while(scanf("%ld",&byte)==1)
	{
		getchar();
		fseek(fp,byte-1L,SEEK_SET);
		while((ch=getc(fp))!=EOF && ch!='\n')
		{
			putchar(ch);
		}
		printf("\n");
		rewind(fp);
		puts("Please enter next byte (q to quit):");
	}
	if((fclose(fp)) !=0)
	{
		fprintf(stderr,"Error to shut file.\n");
	}
	return 0;
}</span>
11.编写一个程序,接受两个命令参数。第一个参数为字符串;第二个为文件名。程序打印文件中包含该字符串的所有行。因为这一任务是面向行而不是面向字符的,所以要使用fgets()而不是getc()。使用标准c库函数strstr()在每一行搜索这一字符串。

<span style="font-family:System;">#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 40

int main(int argc,char *argv[])
{
	char temp[SIZE];
  	FILE *fp;
  	
  	if(argc<3)
  	{
  		printf("Missing parameter.\n");
  		exit(1);
	}
  	
  	if( (fp=fopen(argv[2],"r")) ==NULL)
  	{
  		fprintf(stderr,"Error to open %s document.\n",argv[2]);
  		exit(1);
	}
	
  	while( fgets(temp,SIZE,fp)!=NULL )
  	{
  		if(strstr(temp,argv[1]) != NULL)
  		{
  			fputs(temp,stdout);
		}
 	}
 	
    if( fclose(fp) != 0)
  	{
  		fprintf(stderr,"Error to shut %s document.\n",argv[2]);
	}	
	
	return 0;
}</span>

12.创建一个包含20行,每行30个整数的文本文件。整数在0到9之间,用空格分开。该文件时一个图片的数字表示,从0到9的值代表逐渐增加的灰度。编写一个程序,将文件的内容读入到一个20*30的int数组中。一种将这种数字表示成图片的粗略方法就是让程序使用数组中的数值来初始化一个20*31的字符阵列。0对应空格字符,1对应句号字符,一次类推,较大的值对应占空间较多的字符。比如,可以使用#代表9.每行的最后一个字符(第31个)为空字符,这样数组将包含20个字符串。然后程序显示结果图片(即打印这些字符串),并将结果存入一个文本文件中。例如,如果开始的数据为:

0 0 9 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 2 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 9 0 0 0 0 0 0 0 5 8 9 9 8 5 5 2 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 1 9 8 5 4 5 2 0 0 0 0 0 0 0 0 0
0 0 0 0 9 0 0 0 0 0 0 0 5 8 9 9 8 5 0 4 5 2 0 0 0 0 0 0 0 0
0 0 9 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 4 5 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 1 8 5 0 0 0 4 5 2 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 4 5 2 0 0 0 0 0
5 5 5 5 5 5 5 5 5 5 5 5 5 8 9 9 8 5 5 5 5 5 5 5 5 5 5 5 5 5
8 8 8 8 8 8 8 8 8 8 8 8 5 8 9 9 8 5 8 8 8 8 8 8 8 8 8 8 8 8
9 9 9 9 0 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 3 9 9 9 9 9 9 9
8 8 8 8 8 8 8 8 8 8 8 8 5 8 9 9 8 5 8 8 8 8 8 8 8 8 8 8 8 8
5 5 5 5 5 5 5 5 5 5 5 5 5 8 9 9 8 5 5 5 5 5 5 5 5 5 5 5 5 5
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 6 6 0 0 0 0 0 0
0 0 0 0 2 2 0 0 0 0 0 0 5 8 9 9 8 5 0 0 5 6 0 0 6 5 0 0 0 0
0 0 0 0 3 3 0 0 0 0 0 0 5 8 9 9 8 5 0 5 6 1 1 1 1 6 5 0 0 0
0 0 0 0 4 4 0 0 0 0 0 0 5 8 9 9 8 5 0 0 5 6 0 0 6 5 0 0 0 0
0 0 0 0 5 5 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 6 6 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0
对于特定的输出字符的选择,输出是这样的:
<span style="font-family:System;">/*
0 0 9 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 2 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 9 0 0 0 0 0 0 0 5 8 9 9 8 5 5 2 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 1 9 8 5 4 5 2 0 0 0 0 0 0 0 0 0
0 0 0 0 9 0 0 0 0 0 0 0 5 8 9 9 8 5 0 4 5 2 0 0 0 0 0 0 0 0
0 0 9 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 4 5 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 1 8 5 0 0 0 4 5 2 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 4 5 2 0 0 0 0 0
5 5 5 5 5 5 5 5 5 5 5 5 5 8 9 9 8 5 5 5 5 5 5 5 5 5 5 5 5 5
8 8 8 8 8 8 8 8 8 8 8 8 5 8 9 9 8 5 8 8 8 8 8 8 8 8 8 8 8 8
9 9 9 9 0 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 3 9 9 9 9 9 9 9
8 8 8 8 8 8 8 8 8 8 8 8 5 8 9 9 8 5 8 8 8 8 8 8 8 8 8 8 8 8
5 5 5 5 5 5 5 5 5 5 5 5 5 8 9 9 8 5 5 5 5 5 5 5 5 5 5 5 5 5
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 6 6 0 0 0 0 0 0
0 0 0 0 2 2 0 0 0 0 0 0 5 8 9 9 8 5 0 0 5 6 0 0 6 5 0 0 0 0
0 0 0 0 3 3 0 0 0 0 0 0 5 8 9 9 8 5 0 5 6 1 1 1 1 6 5 0 0 0
0 0 0 0 4 4 0 0 0 0 0 0 5 8 9 9 8 5 0 0 5 6 0 0 6 5 0 0 0 0
0 0 0 0 5 5 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 6 6 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROWS 20
#define COLS 30
int main(void)
{
	FILE *fpArr,*fpStr;
	int array[ROWS][COLS];
	char pic[ROWS][COLS+1];
	const char transform[COLS+1]={' ',  '.',  '\'',  ':',  '`',  '*',  '=',  '!',  '%',  '#', };
	int i,j;
	int ch;
	int index;
	
	if((fpArr=fopen("array.txt","r")) == NULL)
	{
		fprintf(stderr,"Can't  open document \"array.txt\"\n");
		exit(1);
	}
		
	for(i=0;i<ROWS;i++)	//把字符串写入数组 
	{
		j=0;
		while((ch=getc(fpArr)) != '\n' && j<COLS)
		{
			if(ch != ' ')
			{
				array[i][j]=ch-48;
				j++;				
			}
		}
	}
	
	if((fclose(fpArr)) !=0)	//关闭数组文件 
	{
		fprintf(stderr,"Cant't shut document \"array.txt\"\n");
		exit(1);
	}

	if((fpStr=fopen("str.txt","w")) == NULL)
	{
		fprintf(stderr,"Can't  open document \"str.txt\"\n");
		exit(1);
	}	
		
	for(i=0;i<ROWS;i++)	//把数组中的数字转换成图形,并写入pic字符数组 
	{
		for(j=0;j<COLS;j++)
		{
			index=array[i][j];
			pic[i][j]=transform[index];
		}
		pic[i][j]='\0';
		puts(pic[i]);
		fputs(pic[i],fpStr);	//把字符串输出到文件 
		putc('\n',fpStr);		//每行结尾加换行 
	}


	if(fclose(fpStr) != 0)
	{
		fprintf(stderr,"Can't  shut document \"str.txt\"\n");
		exit(1);
	}	
	
	return 0;
}</span>
13.数字图像,尤其是宇宙飞船发回来的数字图像可能会含有尖峰脉冲。为第12道编程练习题添加消除尖峰脉冲的函数。该函数应该将每一个值和它上下左右的相邻值比较,如果该值与他周围每个值得差都都大于1,就用相邻值得平均值(取最接近的整数)代替这个值。注意到便捷上的点的相邻点少于4个,所以他们需要特殊处理。
<span style="font-family:System;">/*
0 0 9 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 2 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 9 0 0 0 0 0 0 0 5 8 9 9 8 5 5 2 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 1 9 8 5 4 5 2 0 0 0 0 0 0 0 0 0
0 0 0 0 9 0 0 0 0 0 0 0 5 8 9 9 8 5 0 4 5 2 0 0 0 0 0 0 0 0
0 0 9 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 4 5 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 1 8 5 0 0 0 4 5 2 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 4 5 2 0 0 0 0 0
5 5 5 5 5 5 5 5 5 5 5 5 5 8 9 9 8 5 5 5 5 5 5 5 5 5 5 5 5 5
8 8 8 8 8 8 8 8 8 8 8 8 5 8 9 9 8 5 8 8 8 8 8 8 8 8 8 8 8 8
9 9 9 9 0 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 3 9 9 9 9 9 9 9
8 8 8 8 8 8 8 8 8 8 8 8 5 8 9 9 8 5 8 8 8 8 8 8 8 8 8 8 8 8
5 5 5 5 5 5 5 5 5 5 5 5 5 8 9 9 8 5 5 5 5 5 5 5 5 5 5 5 5 5
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 6 6 0 0 0 0 0 0
0 0 0 0 2 2 0 0 0 0 0 0 5 8 9 9 8 5 0 0 5 6 0 0 6 5 0 0 0 0
0 0 0 0 3 3 0 0 0 0 0 0 5 8 9 9 8 5 0 5 6 1 1 1 1 6 5 0 0 0
0 0 0 0 4 4 0 0 0 0 0 0 5 8 9 9 8 5 0 0 5 6 0 0 6 5 0 0 0 0
0 0 0 0 5 5 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 6 6 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 5 8 9 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define ROWS 20
#define COLS 30
void adjust(int array[][COLS],int row);
int main(void)
{
	FILE *fpArr,*fpStr;
	int array[ROWS][COLS];
	int copy[ROWS][COLS];
	char pic[ROWS][COLS+1];
	const char transform[COLS+1]={' ',  '.',  '\'',  ':',  '`',  '*',  '=',  '!',  '%',  '#', };
	int i,j;
	int ch;
	int index;
	
	if((fpArr=fopen("array.txt","r")) == NULL)
	{
		fprintf(stderr,"Can't  open document \"array.txt\"\n");
		exit(1);
	}
		
	for(i=0;i<ROWS;i++)	//把字符串写入数组 
	{
		j=0;
		while((ch=getc(fpArr)) != '\n' && j<COLS)
		{
			if(ch != ' ')		//剔除空格 
			{	
				array[i][j]=ch-48;			//把字符转换为int
				j++;				//因为字符文件中剔除空格和换行符的之后,一行字符的个数正好等于数组的一行元素个数。所以在if里面j++是可行的。 
			}
		}
	}
	
	adjust(array,ROWS);
	for(i=0;i<ROWS;i++)
	{
		for(j=0;j<COLS;j++)
		{
			printf("%d ",array[i][j]);
		}
		printf("\n");
	}
	
	if((fclose(fpArr)) !=0)	//关闭数组文件 
	{
		fprintf(stderr,"Cant't shut document \"array.txt\"\n");
		exit(1);
	}

	if((fpStr=fopen("str.txt","w")) == NULL)
	{
		fprintf(stderr,"Can't  open document \"str.txt\"\n");
		exit(1);
	}	
		
	for(i=0;i<ROWS;i++)	//把数组中的数字转换成图形,并写入pic字符数组 
	{
		for(j=0;j<COLS;j++)
		{
			index=array[i][j];
			pic[i][j]=transform[index];
		}
		pic[i][j]='\0';
		puts(pic[i]);
		fputs(pic[i],fpStr);	//把字符串输出到文件 
		putc('\n',fpStr);		//每行结尾加换行 
	}


	if(fclose(fpStr) != 0)
	{
		fprintf(stderr,"Can't  shut document \"str.txt\"\n");
		exit(1);
	}	
	
	return 0;
}

void adjust(int array[][COLS],int row)
{
	int sum=0;
	int count=0;
	int i,j;
	double average;
	int copy[ROWS][COLS];

	//复制参照数组 	
	for(i=0;i<row;i++)		
	{
		for(j=0;j<COLS;j++)
		{
			copy[i][j]=array[i][j];
		}
	}
	//遍历数组寻找尖峰异常数据 
	for(i=0;i<row;i++)	 
	{
		for(j=0;j<COLS;j++)
		{	
			sum=0;
			count=0;		
			
			if(i-1>=0)	 //判断上一行的是否在数组内 
			{
				if(fabs(copy[i][j]-copy[i-1][j])>1)	//如果上一行在数组内,则判断与它的差的绝对值是否大于1 
				{
					sum=sum+copy[i-1][j];				//大于1则 为计算平均值保存数据 
					count++;							
				}
				else
					continue;						//有一个不大于1,则不在计算了,直接continue跳出本轮,j++,计算下一轮 
			}
			if(i+1<row)
			{
				if(fabs(copy[i][j]-copy[i+1][j])>1)
				{				
					sum=sum+copy[i+1][j];
					count++;		
				}
				else
					continue;
			}
			if(j-1>=0)
			{
				if(fabs(copy[i][j]-copy[i][j-1])>1)
				{			
					sum=sum+copy[i][j-1];
					count++;						
				}
				else
					continue;
			}
			if(j+1<COLS)
			{
				if(fabs(copy[i][j]-copy[i][j+1])>1)
				{			
					sum=sum+copy[i][j+1];
					count++;				
				}
				else
					continue;
			}
			//只有上面4个if条件都满足,才能执行到这,并且四舍五入到最接近的整数,替换原数组数值 
			average=sum/count;	 
			array[i][j]=average+0.5;	//四舍五入调整原数组			
		}	
	}
}</span>










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值