C Primer Plus第六版第十三章编程题目与参考答案⭐

1、修改程序清单13.1中的程序,要求提示用户输入文件名,并读取用户输入的信息,不使用命令行参数。

# include <stdio.h>
# include <stdlib.h>
 
int main(void)
{
	int ch ;
	FILE * fp ;
	char st[100];
	unsigned long count = 0 ;
 
	printf("Please enter filename:");
	scanf("%s" , st);
 
	if ((fp = fopen(st , "r")) == NULL)
	{
		printf("Can't open %s\n" , st);
		exit(EXIT_FAILURE);
	}
 
	while ((ch = getc(fp)) != EOF)
	{
		putc(ch , stdout);
		count++ ;
	}
	fclose(fp);
	printf("File %s has %lu characters\n" , st, count);
 
	return 0 ;
}

2.编写一个文件拷贝程序,该程序通过命令行获取原始文件名和拷贝文件名。尽量使用标准I/O和二进制模式。

# include <stdio.h>
# include <stdlib.h>
 
int main(int argc , char * argv[])
{
	FILE * in , * out ;
	char ch ;
	size_t byt ;
 
	if (argc != 3)
	{
		fprintf(stderr , "错误的参数.\n");
		exit(EXIT_FAILURE);
	}
 
	if ((in = fopen(argv[1] , "rb")) == NULL)
	{
		fprintf(stderr , "打不开文件%s.\n" , argv[1]);
		exit(EXIT_FAILURE);
	}
 
	if ((out = fopen(argv[2] , "wb")) == NULL)
	{
		fprintf(stderr , "打不开文件%s.\n" , argv[2]);
		exit(EXIT_FAILURE);
	}
 
	while ((byt = fread(&ch , sizeof(ch) , 1 , in)) && !feof(in))
		fwrite(&ch , sizeof(ch) ,1 , out);
 
	if (fclose(in) || fclose(out))
	{
		fprintf(stderr , "退出失败.\n");
		exit(EXIT_FAILURE);
	}
 
	return 0 ;
}

3.编写一个文件拷贝程序,提示用户输入文本文件名,并以该文件名作为原始文件名和输出文件名。该程序要使用ctype.h中的 toupper ()函数,在写入到输出文件时把所有文本转换成大写。使用标准IO和文本模式。

# include <stdio.h>
# include <stdlib.h>
# include <ctype.h>
 
int main(void)
{
	char file[100];
	char ch ;
	FILE * fp ;
 
	puts("Please enter file name :");
	scanf("%s" , file);
 
	if ((fp = fopen(file , "r+")) == NULL)
	{
		printf("Can't open the %s\n" , file);
		exit(EXIT_FAILURE);
	}
 
	while ((ch = fgetc(fp)) != EOF)
	{
		if (islower(ch))
		{
			//当指定了“r+”、“w+”或“a+”访问类型时,
			//将同时启用读写(文件被称为打开进行“更新”)。
			//但是,当您从读取切换到写入时,输入操作必须遇到
			//一个EOF标记。如果没有eof,则必须使用对文件定位函数的中间调用。
			//以上就是我费尽九牛二虎之力查到的,如果没有重新定位,将无法写入
			//我试过了很多方法
			fseek(fp , - 1 , SEEK_CUR); //回退一个字符
			putc(toupper(ch) , fp);
			fseek(fp , 0 , SEEK_CUR);   //定位到当前字符位置
		}
	} 
	
	if (fclose(fp) != 0)
		printf("Error in closing files.\n");
 
	return 0 ;
}

4.编写一个程序,按顺序在屏幕上显示命令行中列出的所有文件。使用argc控制循环。

# include <stdio.h>
# include <stdlib.h>
 
int main(int argc , char * argv[])
{
	FILE * fp ;
	char ch ;
 
	while (--argc > 0)
	{
		if (!(fp = fopen(*++argv , "r")))
		{
			fprintf(stderr , "打开%s文件失败.\n" , *argv);
			continue ;
		}
		
		while ((ch = getc(fp)) != EOF)	
			putc(ch ,stdout);
 
		if (fclose(fp))
		{
			fprintf(stderr , "退出%s文件失败.\n" , *argv);
			exit(EXIT_FAILURE);
		}
	}
 
	return 0 ;
}

5.修改程序清单13.5中的程序,用命令行界面代替交互式界面。
13.5程序如下:
在这里插入图片描述

在这里插入图片描述
参考答案

# include <stdio.h>
# include <stdlib.h>
# include <string.h>
 
# define BUFSIZE 4096
 
void append(FILE * source , FILE * dest);
char * s_gets(char * st , int n);
 
int main(int argc , char * argv[])
{
	FILE * fa , * fs ;
	int files = 0 ;
	int ch ;
 
	if (argc < 3)
	{
		fprintf(stderr , "参数错误.\n");
		exit(EXIT_FAILURE);
	}
 
	if ((fa = fopen(argv[1] , "a+")) == NULL)
	{
		fprintf(stderr , "Can't open %s\n" , argv[1]);
		exit(EXIT_FAILURE);
	}
 
	if (setvbuf(fa , NULL , _IOFBF , BUFSIZE) != 0)
	{
		fputs("Can't create output buffer\n" , stderr);
		exit(EXIT_FAILURE);
	}
 
	for(int i = 2 ; i < argc ; i++)
	{
		if (strcmp(argv[1] , argv[i]) == 0)
			fputs("Can't append file to itself\n" , stderr);
		else if ((fs = fopen(argv[i] , "r")) == NULL)
			fprintf(stderr , "Can't open %s\n" , argv[i]);
		else
		{
			if (setvbuf(fs , NULL , _IOFBF , BUFSIZE) != 0)
			{
				fputs("Can't create input buffer\n" , stderr);
				fclose(fs);
				continue ;
			}
 
			append(fs , fa);
 
			if (ferror(fs) != 0)
				fprintf(stderr , "Error in reading file %s.\n" , argv[i]);
			if (ferror(fa) != 0)
				fprintf(stderr , "Error in writing file %s.\n" , argv[1]);
 
			fclose(fs);
			files++ ;
			printf("File %s appended.\n" , argv[i]);
		}
	}
	printf("Done appending. %d files appended.\n" , files);
	rewind(fa);
	printf("%s contents:\n" , argv[1]);
	while ((ch = getc(fa)) != EOF)
		putchar(ch);
	puts("Done displaying.");
	fclose(fa);
 
	return 0 ;
}
 
void append(FILE * source , FILE * dest)
{
	size_t bytes ;
	static char temp[BUFSIZE] ;
 
	while ((bytes = fread(temp , sizeof(char) , BUFSIZE , source)) > 0)
		fwrite(temp , sizeof(char) , bytes , dest);
}
 
char * s_gets(char * st , int n)
{
	char * ret_val ;
	char * find ;
 
	ret_val = fgets(st , n , stdin);
	if (ret_val)
	{
		find = strchr(st , '\n');
		if (find)
			*find = '\0' ;
		else 
			while (getchar() != '\n') ;
	}
 
	return ret_val;
}

6.使用命令行参数的程序依赖于用户的内存如何正确地使用它们。重写程序清单13.2中的程序,不使用命令行参数,而是提示用户输入所需信息。

# include <stdio.h>
# include <stdlib.h>
# include <string.h>
 
# define LEN 40
 
int main(void)
{
	FILE * in , * out ;
	int ch ;
	char name[LEN] ;
	int count = 0 ;
	char file[LEN] ;
	char * pch ;
 
	puts("Please enter file name :");
	scanf("%s" , file);
 
	if ((in = fopen(file , "r")) == NULL)
	{
		fprintf(stderr , "I couldn't open the file \"%s\"\n" ,file);
		exit(EXIT_FAILURE);
	}
 
	// 这里源码拷贝了保证了足够的空间容纳后缀字符
	strncpy(name , file ,LEN - 5);
	name[LEN - 5] = '\0' ;
 
	// 我优化了添加后缀的方式,用户可能输入带后缀的文件,也可能是不带后缀的文件
	if (pch = strchr(name , '.'))
		*pch = '\0';
	strcat(name , ".red");
 
	if ((out = fopen(name , "w")) == NULL)
	{
		fprintf(stderr , "Can't create output file.\n");
		exit(3);
	}
 
	while ((ch = getc(in)) != EOF)
	{
		if (count++ % 3 == 0)
			putc(ch , out);
	}
 
	if (fclose(in) != 0 || fclose(out) != 0)
		fprintf(stderr , "Error in closing files\n");
 
	return 0 ;
}

7.编写一个程序打开两个文件。可以使用命令行参数或提示用户输入文件名。

# include <stdio.h>
# include <stdlib.h>
 
# define LEN 100
 
void function_a(FILE * f1 , FILE * f2);
void function_b(FILE * f1 , FILE * f2);
 
int main(int argc , char * argv[])
{
	FILE * fp1 , * fp2 ;
 
	if (argc != 3)
	{
		fprintf(stderr , "参数错误");
		exit(EXIT_FAILURE);
	}
 
	if (!(fp1 = fopen(argv[1] , "r")))
	{
		fprintf(stderr , "%s 文件无法打开.\n" , argv[1]);
		exit(EXIT_FAILURE);
	}
 
	if (!(fp2 = fopen(argv[2] , "r")))
	{
		fprintf(stderr , "%s 文件无法打开.\n" , argv[2]);
		exit(EXIT_FAILURE);
	}
 
	puts("a小题执行结果:");
	function_a(fp1 , fp2) ;
 
	//重新回到文件头
	rewind(fp1);
	rewind(fp2);
 
	puts("b小题执行结果:");
	function_b(fp1 , fp2) ;
 
	if (fclose(fp1) || fclose(fp2))
		fprintf(stderr , "文件关闭失败.\n");
	
	return 0 ;
}
 
void function_a(FILE * f1 , FILE * f2)
{
	char ch1 , ch2 ;
 
	do
	{
		while ((ch1 = getc(f1)) != EOF && ch1 != '\n')
		{
			putc(ch1 ,stdout) ;
			putchar('\n');
		}
 
		while ((ch2 = getc(f2)) != EOF && ch2 != '\n')
		{
			putc(ch2 ,stdout) ;
			putchar('\n');
		}
 
	}while (ch1 != EOF && ch2 != EOF) ;
}
 
void function_b(FILE * f1 , FILE * f2)
{
	char ch1 , ch2 ;
 
	do
	{
		while ((ch1 = getc(f1)) != EOF && ch1 != '\n')
		{
			putc(ch1 ,stdout) ;
		}
 
		while ((ch2 = getc(f2)) != EOF && ch2 != '\n')
		{
			putc(ch2 ,stdout) ;
		}
		putchar('\n');
 
	}while (ch1 != EOF && ch2 != EOF) ;
}

a.该程序以这样的顺序打印:打印第1个文件的第1行,第2个文件的第1行,第1个文件的第2行,第2个文件的第2行,以此类推,打印到行数较多文件的最后一行。
b.修改该程序,把行号相同的行打印成一行。

8.编写一个程序,以一个字符和任意文件名作为命令行参数。如果字符后面没有参数,该程序读取标准输入;否则,程序依次打开每个文件并报告每个文件中该字符出现的次数。文件名和字符本身也要一同报告。程序应包含错误检查,以确定参数数量是否正确和是否能打开文件。如果无法打开文件,程序应报告这一情况,然后继续处理下一个文件。

# include <stdio.h>
# include <stdlib.h>
 
long filechr(int ch , FILE * fp);
 
int main(int argc , char * argv[])
{
	FILE * fp ;
 
	if (argc < 2)
	{
		fprintf(stderr , "参数错误.\n");
		exit(EXIT_FAILURE);
	}
	else if (argc == 2)
	{
		printf("请输入你要检查%s存在次数的内容(结束符停止)\n" , argv[1]);
		printf("您输入的内容中%s出现了%ld次.\n", argv[1] , filechr(*argv[1] , stdin));
	}
	else 
	{
		for (int i = 2 ; i < argc ; i++)
		{
			if (!(fp = fopen(argv[i] , "r")))
			{
				fprintf(stderr , "%s文件无法打开.\n" , argv[i]);
				continue ;
			}
			printf("文件%s中%s出现了%ld次.\n" , argv[i] , argv[1] , filechr(*argv[1] , fp));
			if (fclose(fp))
			{
				fprintf(stderr , "%s文件退出失败.\n" , argv[i]);
				exit(EXIT_FAILURE);
			}
		}
	}
 
	return 0 ;
}
 
long filechr(int ch , FILE * fp)
{
	long ret_val = 0 ;
	char tmp ;
 
	while ((tmp = getc(fp)) != EOF)
	{
		if (ch == tmp)
			ret_val++ ;
	}
	return ret_val; 
}

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

# include <stdio.h>
# include <stdlib.h>
# include <string.h>
 
# define MAX 41
 
int main(void)
{
	FILE * fp ;
	char words[MAX] ;
	long num = 0 ;
 
	if ((fp = fopen("wordy" , "a+")) == NULL)
	{
		fprintf(stderr , "Can't open \"wordy\" file.\n");
		exit(EXIT_FAILURE);
	}
 
	//读出原数据
	while (fscanf(fp , "%ld %s \n" , &num , words) > 0) ;
 
	puts("Enter words to add to the file; press the #");
	puts("key at the beginning of a line to terminate.");
	while ((fscanf(stdin , "%40s" , words)) == 1 && (words[0] != '#'))
		fprintf(fp , "%ld %s\n" , ++num , words); //将编号自增后也写入文件内
 
	puts("File contents:");
	rewind(fp);
	while (fscanf(fp , "%ld %s\n" , &num , words) == 2)
		fprintf(stdout , "%ld %s\n" , num , words);
	puts("Done!");
	if (fclose(fp) != 0)
		fprintf(stderr , "Error closing file.\n");
 
	return 0 ;
}

10.编写一个程序打开一个文本文件,通过交互方式获得文件名。通过一个循环,提示用户输入一个文件位置。然后该程序打印从该位置开始到下一个换行符之前的内容。用户输入负数或非数值字符可以结束输入循环。

# include <stdio.h>
# include <stdlib.h>
 
# define LEN 100
 
int main(void)
{
	long num ;
	char fname[LEN] ;
	char ch ;
	FILE * fp ;
 
	puts("Please enter file name:");
	scanf("%s" , fname);
 
	if (!(fp = fopen(fname , "r")))
	{
		fprintf(stderr , "Can't open file %s.\n" , fname);
		exit(EXIT_FAILURE);
	}
 
	puts("Please enter a number:(< 0 to quit)");
	while (scanf("%ld" , &num) && num >= 0)
	{
		while (getchar() != '\n') ; 
 
		fseek(fp , num , SEEK_SET); //定位到指定位置
 
		while ((ch = getc(fp)) != '\n') //从指定位置输出字符直到遇到\n
			putc(ch , stdout) ;
		putchar('\n');//换行
 
		puts("Please enter a number:(< 0 to quit)");
	}
	
	puts("Done !");
 
	return 0 ;
}

11.编写一个程序,接受两个命令行参数。第Ⅰ个参数是一个字符串,第2个参数是一个文件名。然后该程序查找该文件,打印文件中包含该字符串的所有行。因为该任务是面向行而不是面向字符的,所以要使用fgets ()而不是getc()。使用标准C库函数strstr ( ) (11.5.7节简要介绍过)在每一行中查找指定字符串。假设文件中的所有行都不超过255个字符。

# include <stdio.h>
# include <stdlib.h>
# include <string.h>
 
# define LEN 255 
 
int main(int argc , char * argv[])
{
	char line[LEN] ;
	FILE * fp ;
 
	if (argc != 3)
	{
		fputs("参数错误.\n" , stderr);
		exit(EXIT_FAILURE);
	}
 
	if (!(fp = fopen(argv[2] , "r")))
	{
		fprintf(stderr , "无法打开文件:%s\n" , argv[2]);
		exit(EXIT_FAILURE);
	}
 
	while (fgets(line , LEN , fp))
	{
		if (strstr(line , argv[1]))
			fputs(line , stdout);
	}
 
	if (fclose(fp))
	{
		fputs("文件退出失败.\n" , stderr);
		exit(EXIT_FAILURE);
	}
 
	return 0 ;
}

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 9 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>
 
# define FNAME "no12.txt"
# define FARGS "no12.dat"
# define STR " .':~*=&%#"
 
int main(void)
{
	FILE * fp , * ft;
	int ar[20][30] ;
	char st[20][31] ;
 
	if (!(fp = fopen(FNAME, "r")))
	{
		fprintf(stderr , "Can't open file %s.\n" ,FNAME) ; 
		exit(EXIT_FAILURE);
	}
 
	if (!(ft = fopen(FARGS , "w")))
	{
		fprintf(stderr , "Can't open file %s.\n" ,FARGS);
		exit(EXIT_FAILURE);
	}
 
	// 读取文件中的内容到整型数组
	for (int i = 0 ; i < 20 ; i++)	
		for (int j = 0 ; j < 30 ; j++)
			//这样做是为了确保fscanf()正确读到1个数,而不受空格和其他字符影响
			while (fscanf(fp ,"%d" , &ar[i][j]) != 1)
				fscanf(fp ,"%*c");
 
	// 初始化字符串数组
	for (int j ,i = 0 ; i < 20 ; i++)
	{
		for ( j = 0 ; j < 30 ; j++)
			st[i][j] = *(STR + ar[i][j]);
		st[i][j] = '\0' ;
		fprintf(ft ,"%s\n" ,st[i] );
	}
	
	if (fclose(fp) || fclose(ft))	
	{
		fprintf(stderr , "Clossing error .\n");
		exit(EXIT_FAILURE);
	}
	
	return 0 ;
}

13.用变长数组(VLA)代替标准数组,完成编程练习12。

# include <stdio.h>
# include <stdlib.h>
 
# define ROWS 20
# define COLS 30
# define FNAME "no12.txt"
# define FARGS "no12.dat"
# define STR " .':~*=&%#"
 
void initialize_ar(FILE * fp ,int n , int m , int ar[n][m]);
void set_st(int n , int m , char st[n][m + 1] , int ar[n][m]);
 
int main(void)
{
	FILE * fp , * ft;
	int ar[ROWS][COLS] ;
	char st[ROWS][COLS + 1] ;
 
	if (!(fp = fopen(FNAME, "r")))
	{
		fprintf(stderr , "Can't open file %s.\n" ,FNAME) ; 
		exit(EXIT_FAILURE);
	}
 
	if (!(ft = fopen(FARGS , "w")))
	{
		fprintf(stderr , "Can't open file %s.\n" ,FARGS);
		exit(EXIT_FAILURE);
	}
 
	initialize_ar(fp , ROWS , COLS , ar) ;
	set_st(ROWS , COLS , st , ar) ;
 
	for (int i = 0 ; i < ROWS ; i++)
		fprintf(ft ,"%s\n" ,st[i] );
	
	if (fclose(fp) || fclose(ft))	
	{
		fprintf(stderr , "Clossing error .\n");
		exit(EXIT_FAILURE);
	}
	
	return 0 ;
}
 
void initialize_ar(FILE * fp ,int n , int m , int ar[n][m])
{
	// 读取文件中的内容到整型数组
	for (int i = 0 ; i < n ; i++)	
		for (int j = 0 ; j < m ; j++)
			//这样做是为了确保fscanf()正确读到1个数,而不受空格和其他字符影响
			while (fscanf(fp ,"%d" , &ar[i][j]) != 1)
				fscanf(fp ,"%*c");
}
 
void set_st(int n , int m , char st[n][m + 1] , int ar[n][m])
{
	int i , j ;
 
	for (i = 0 ; i < n ; i++)
	{
		for (j = 0 ; j < m ; j++)
		{
			st[i][j] = *(STR + ar[i][j]) ;
		}
		st[i][j] = '\0' ;
	}
}

14.数字图像,尤其是从宇宙飞船发回的数字图像,可能会包含一些失真。为编程练习12添加消除失真的函数。该函数把每个值与它上下左右相邻的值作比较,如果该值与其周围相邻值的差都大于1,则用所有相邻值的平均值(四舍五入为整数)代替该值。注意,与边界上的点相邻的点少于4个,所以做特殊处理。

# include <stdio.h>
# include <stdlib.h>
# include <math.h>
 
# define ROWS 20
# define COLS 30
# define FNAME "no12.txt"
# define FARGS "no12.dat"
# define STR " .':~*=&%#"
 
void initialize_ar(FILE * fp ,int n , int m , int ar[n][m]);
void set_st(int n , int m , char st[n][m + 1] , int ar[n][m]);
void reconstruction(int n , int m , int ar[n][m]);
 
int main(void)
{
	FILE * fp , * ft;
	int ar[ROWS][COLS] ;
	char st[ROWS][COLS + 1] ;
 
	if (!(fp = fopen(FNAME, "r")))
	{
		fprintf(stderr , "Can't open file %s.\n" ,FNAME) ; 
		exit(EXIT_FAILURE);
	}
 
	if (!(ft = fopen(FARGS , "w")))
	{
		fprintf(stderr , "Can't open file %s.\n" ,FARGS);
		exit(EXIT_FAILURE);
	}
 
	initialize_ar(fp , ROWS , COLS , ar) ;
	reconstruction(ROWS , COLS ,ar) ;
	set_st(ROWS , COLS , st , ar) ;
 
	for (int i = 0 ; i < ROWS ; i++)
		fprintf(ft ,"%s\n" ,st[i] );
	
	if (fclose(fp) || fclose(ft))	
	{
		fprintf(stderr , "Clossing error .\n");
		exit(EXIT_FAILURE);
	}
	
	return 0 ;
}
 
void initialize_ar(FILE * fp ,int n , int m , int ar[n][m])
{
	// 读取文件中的内容到整型数组
	for (int i = 0 ; i < n ; i++)	
		for (int j = 0 ; j < m ; j++)
			//这样做是为了确保fscanf()正确读到1个数,而不受空格和其他字符影响
			while (fscanf(fp ,"%d" , &ar[i][j]) != 1)
				fscanf(fp ,"%*c");
}
 
void set_st(int n , int m , char st[n][m + 1] , int ar[n][m])
{
	int i , j ;
 
	for (i = 0 ; i < n ; i++)
	{
		for (j = 0 ; j < m ; j++)
		{
			st[i][j] = *(STR + ar[i][j]) ;
		}
		st[i][j] = '\0' ;
	}
}
 
void reconstruction(int n , int m , int ar[n][m])
{
	int left , right , up , down ;
	int l , r , u , d ;
	int sum ;
	int count ;
 
	for (int i = 0 ; i < n ; i++)
	{
		for (int j = 0 ; j < m ; j++)
		{
			//left = right = up = down = -1 ;
			l = r = u = d = 1;
			sum = 0 ;
			count = 0 ;
 
			if (j > 0)
			{
				//left = ar[i][m - 1] ;
				l = abs(ar[i][j] - ar[i][j - 1]) > 1 ? 1 : 0 ;
				sum += ar[i][j - 1] ;
				count++ ;
			}
 
			if (j < m - 1)
			{
				r = abs(ar[i][j] - ar[i][j + 1]) > 1 ? 1 : 0 ;
				sum += ar[i][j + 1] ;
				count++ ;
				//right = ar[i][m + 1] ;
			}
			if (i > 0)
			{
				u = abs(ar[i][j] - ar[i - 1][j]) > 1 ? 1 : 0 ;
				sum += ar[i - 1][j] ;
				count++ ;
				//up = ar[i - 1][m] ;
			}
			if (i < n - 1)
			{
				d = abs(ar[i][j] - ar[i + 1][j]) > 1 ? 1 : 0 ;
				sum += ar[i + 1][j] ;
				count++ ;
				//down = ar[i + 1][m] ;
			}
 
			if (l && r && u && d)
			{
				ar[i][j] = sum / (double)count ;
			}
			/*
			if ((abs(left - ar[i][j]) > 1) && (abs(right - ar[i][j]) > 1)
					&& (abs(up - ar[i][j]) > 1) && (abs(down - ar[i][j]) > 1))
				ar[i][j] = (left + right + up + down) / 4.0 ;
			*/
		}
	}
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值