C Primer Plus 第十三章 编程练习13

作者在 2013-05-14 12:50:03 发布以下内容
/*
创建一个包含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
*/
/*
数字图像,尤其是从宇宙飞船发回的数字图像可能会包含尖峰脉冲.
为程序添加消除尖峰脉冲的函数.
该函数应该将每一个值和它上下左右的相邻值比较,如果该值与它周围每个值的差都大于1
,就用所有相邻值的平均值(取与其最接近的整数)取代这个值.
注意:边界上的点的相邻点少于4个.所以需要特殊处理. 
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ROWS 20				/*数组行数*/
#define INT_ROLS 30			/*INT数组列数*/
#define CHAR_ROLS 31		/*CHAR数组列数*/
#define BUFSIZE 60			/*fgets()每次读取字符个数*/
#define CHAR_TO_INT 48		/*CHAR类型转INT*/
 
void saveToArray(FILE *, int [][INT_ROLS]);			/*从文件中将数据保存到数组中*/
void change(int [][INT_ROLS], char [][CHAR_ROLS]);	/*将INT数组中的元素转义后保存到CHAR数组*/
void display(char [][CHAR_ROLS]);					/*在屏幕显示字符数组内容*/
void saveToFile(char [][CHAR_ROLS]);				/*将CHAR数组内容写入文件*/
void clear(int [][INT_ROLS]);						/*消除尖峰脉冲*/

int main(int argc, char *argv[])
{
    int sources[ROWS][INT_ROLS] = {0};				/*保存数字的数组*/
    char target[ROWS][CHAR_ROLS];					/*保存转义后的字符的数组*/
    FILE *fp;										/*文件指针*/
    int i, j;										/*循环变量*/
     
    if((fp = fopen("cpp_13.11_12.txt", "r")) == NULL)
    {
        fprintf(stderr, "Can't open file :\"cpp_13.11_12.txt\".\n");
        exit(1);
    }
 
    saveToArray(fp, sources);		/*读取文件内容保存到INT数组*/
    fclose(fp);						/*关闭文件*/
    
	clear(sources);					/*消除尖峰脉冲*/ 
    change(sources, target);		/*转义*/
    display(target);				/*显示字符*/
	saveToFile(target);				/*存入文件*/ 
    
    printf("\n\nDone.\n");
    return 0;
}
 
void saveToArray(FILE * fp, int sources[][INT_ROLS])
{
    int *psl;
    char tmp[BUFSIZE];
    char *p;
 
    psl = *sources;
     
    while(fgets(tmp, BUFSIZE, fp) != NULL)  /*从文件读入数字,存入INT数组*/
    {
        p = tmp;
        while(*p)
        {
            if(*p != ' ' && *p != '\n')
                *psl++ = (int)*p - CHAR_TO_INT;
 
            p++;
        }
    }
}
 
void change(int sources[][INT_ROLS], char target[][CHAR_ROLS])
{
    int (*psw)[INT_ROLS];
    int *psl;
    char (*ptw)[CHAR_ROLS];
    char *ptl;
     
    for(psw = sources, ptw = target; psw < sources + ROWS; psw++, ptw++)
    {
        for(psl = *psw, ptl = *ptw; psl < *psw + INT_ROLS; psl++, ptl++)
        {
            switch(*psl){
            case 0:*ptl = ' ';break;
            case 1:*ptl = '.';break;
            case 2:*ptl = '\'';break;
            case 3:*ptl = ':';break;
            case 4:*ptl = '~';break;
            case 5:*ptl = '*';break;
            case 6:*ptl = '=';break;
            case 7:*ptl = '!';break;
            case 8:*ptl = '%';break;
            case 9:*ptl = '#';break;
            }   
        }
         
        *ptl = '\0';					/*在每行最后一位加入字符串结束符号*/
    }
}

void display(char target[][CHAR_ROLS])
{
	int i;
	
	for(i = 0; i < ROWS; i++)
            puts(target[i]);

}

void saveToFile(char target[][CHAR_ROLS])
{
	FILE *fp;
	int i;
	
    if((fp = fopen("char.txt", "w")) == NULL)
    {
        fprintf(stderr, "Can't create file :\"char.txt\".\n");
        exit(2);
    }
    for(i = 0; i < ROWS; i++)
    {
        fputs(target[i], fp);
        putc('\n', fp);
    }
     
    fclose(fp);
}

void clear(int ar[][INT_ROLS])
{
	int (*pw)[INT_ROLS], *p;

	int four_horn(int *, int [][INT_ROLS]);	/*判断四角函数*/
	int left_border(int *, int [][INT_ROLS], int [][INT_ROLS]);	/*判断左边界函数*/
	int right_border(int *, int [][INT_ROLS], int [][INT_ROLS]);	/*判断右边界函数*/
	int up_border(int *, int [][INT_ROLS], int [][INT_ROLS]);	/*判断上边界函数*/
	int down_border(int *, int [][INT_ROLS], int [][INT_ROLS]);	/*判断下边界函数*/
	int other(int *, int[][INT_ROLS], int [][INT_ROLS]);			/*非边界函数*/
	
	for(pw = ar; pw < ar + ROWS; pw++)
		for(p = *pw; p < *pw + INT_ROLS; p++)
		{
			if(p == *ar || p == *(ar + 1) - 1 || p == *(ar + ROWS - 1) || p == *(ar + ROWS) - 1)	/*四角判断*/
				*p = four_horn(p, ar);
			 
			else if(p == *pw)					/*左边界判断*/
				*p = left_border(p, ar, pw);	
			else if(p == *(pw + 1) - 1)			/*右边界判断*/
				*p = right_border(p, ar, pw);
			else if(pw == ar)					/*上边界判断*/
				*p = up_border(p, ar, pw);
			else if(pw == (ar + ROWS - 1))		/*下边界判断*/
				*p = down_border(p, ar, pw);
			else
				*p = other(p, ar, pw);
		}
}

int left_border(int *p, int ar[][INT_ROLS], int pw[][INT_ROLS])
{
	int up, down, right;
	
	/*除了左上角和左下角,计算上下右的值,如果差都大于1,计算上下右的平均值*/
	up = (up = *p - **(ar + ROWS - 2)) > 0 ? up : -up;
	down = (down = *p - **(ar + 1)) > 0 ? down : -down;
	right = (right = *p - *(p + 1)) > 0 ? right : -right;
		
	if(up > 1 && right > 1 && down > 1)
		*p = (**(ar + ROWS - 2) + **(ar + 1) + *(p + 1)) / 3;
	
	return *p;
}

int right_border(int *p, int ar[][INT_ROLS], int pw[][INT_ROLS])
{
	int up, down, left;
	
	/*除了左上角和左下角,如果差都大于1,计算上下左的平均值*/
	up = (up = *p - **(ar + ROWS - 2)) > 0 ? up : -up;
	down = (down = *p - **(ar + 1)) > 0 ? down : -down;
	left = (left = *p - *(p - 1)) > 0? left : -left;
		
	if(up > 1 && down > 1 && left > 1)
		*p = (**(ar + ROWS - 2) + **(ar + 1) + *(p - 1)) / 3;
	
	return *p;
}

int up_border(int *p, int ar[][INT_ROLS], int pw[][INT_ROLS])
{
	int left, right, down;
	
	/*除了左上角和右上角,其他上边界的值判断*/
	left = (left = *p - *(p - 1)) > 0? left : -left;
	right = (right = *p - *(p + 1)) > 0 ? right : -right;
	down = (down = *p - *(p + INT_ROLS)) > 0 ? down : -down;
	
	if(left > 0 && right > 0 && down > 0)
		*p = (*(p - 1) + *(p + 1) + *(p + INT_ROLS)) / 3;
		
	return *p;
}

int down_border(int *p, int ar[][INT_ROLS], int pw[][INT_ROLS])
{
	int left, right, up;
	
	/*除了左下角和右下角,其他上边界的值判断*/
	left = (left = *p - *(p - 1)) > 0? left : -left;
	right = (right = *p - *(p + 1)) > 0 ? right : -right;
	up = (up = *p - *(p - INT_ROLS)) > 0 ? up : -up;
	
	if(left > 0 && right > 0 && up > 0)
		*p = (*(p - 1) + *(p + 1) + *(p - INT_ROLS)) / 3;
	
}

int other(int *p, int ar[][INT_ROLS], int pw[][INT_ROLS])
{
	int up, down, left, right;
	
	/*除了四条边界,其他值判断*/
	up = (up = *p - *(p - INT_ROLS)) > 0 ? up : -up;
	down = (down = *p - *(p + INT_ROLS)) > 0 ? down : -down;
	left = (left = *p - *(p - 1)) > 0? left : -left;
	right = (right = *p - *(p + 1)) > 0 ? right : -right;
	
	if(up > 1 && down > 1 && left > 1 && right > 1)
		*p = (*(p - 1) + *(p + 1) + *(p + INT_ROLS) + *(p - INT_ROLS)) / 4;
		
	return *p;
}


int four_horn(int *p, int ar[][INT_ROLS])
{
	int up, down, right, left;
	
	if(p == *ar)	/*左上角*/ 
	{
		right = (right = *p - *(p + 1)) > 0 ? right : -right;			
		down = (down = *p - **(ar + 1)) > 0 ? down : -down;
				
		if(right > 1 && down > 1)
			*p = (*(p + 1) + **(ar + 1)) / 2;
	}
	else if(p == *(ar + 1) - 1)	/*右上角*/
	{
		left = (left = *p - *(p - 1)) > 0? left : -left;
		down = (down = *p - *(*(ar + 2) - 1)) > 0? down : -down;
			
		if(left > 1 && down > 1)
			*p = (*(p - 1) + *(*(ar + 2) - 1)) / 2;
	}
	else if(p == *(ar + ROWS - 1))	/*左下角*/
	{
		up = (up = *p - **(ar + ROWS - 2)) > 0 ? up : -up;
		right = (right = *p - *(p + 1)) > 0 ? right : -right;
						
		if(up > 1 && right > 1)
			*p = (**(ar + ROWS - 2) + *(p + 1)) / 2;
	}
	else if(p == *(ar + ROWS) - 1)	/*右下角*/
	{
		up = (up = *p - *(*(ar + ROWS - 1) - 1)) > 0 ? up : -up;
		left = (left = *p - *(p - 1)) > 0 ? left : -left;
			
		if(up > 1 && left > 1)
			*p = (*(*(ar + ROWS - 1) - 1) + *(p - 1)) / 2;
	}
	
	return *p;
}
文章评论,共0条
游客请输入验证码
浏览41411次