修改程序清单中13.1中的程序,要求提示用户输入文件名,并读取用户输入的信息,不使用命令行参数。
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[]){
int ch;
char name[40];
FILE *fp;
unsigned long count = 0;
printf("请输入文件名:");
scanf("%s", name);
if((fp=fopen(name,"r"))==NULL){
printf("Can`t open %s \n", argv[1]);
exit(EXIT_FAILURE);
}
while((ch=getc(fp))!=EOF){
putc(ch, stdout);
++count;
}
fclose(fp);
printf("File %s has %lu characters\n", name, count);
return 0;
}
文档内容:
abc 123 ref 345
dog is running
cat is running
编写一个文件拷贝程序,该程序通过命令行获取原始文件名和拷贝文件名。尽量使用标准I/O和二进制模式。
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[]){
if(argc<3){
printf("请按照程序 输入文件名 输出文件名 格式进行输入\n");
exit(EXIT_FAILURE);
}
FILE *in,*out;
if((in=fopen(argv[1],"r")) == NULL){
printf("%s 打开失败!\n", argv[1]);
exit(EXIT_FAILURE);
}
if((out=fopen(argv[2],"w"))==NULL){
printf("%s 打开失败!\n", argv[2]);
exit(EXIT_FAILURE);
}
char ch;
while((ch = getc(in)) && ch != EOF)
putc(ch,out);
fclose(in);
fclose(out);
return 0;
}
原始文档:
#include<iostream>
int main(void){
const int i;
return 0;
}
拷贝后文档:
#include<iostream>
int main(void){
const int i;
return 0;
}
编写一个文件拷贝程序,提示用户输入文本文件名,并以该文件名作为原始文件名和输出文件名。该程序要使用ctype.h中的toupper函数,在写入到输出文件时把所有文本转换成大写。使用标准I/O和文本模式
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[]){
char name[40];
char name2[40];
printf("请输入文件名:");
scanf("%s", name);
printf("请输出文件名:");
scanf("%s", name2);
FILE *in,*out;
if((in=fopen(name,"r")) == NULL){
printf("%s 打开失败!\n", name);
exit(EXIT_FAILURE);
}
if((out=fopen(name2,"w"))==NULL){
printf("%s 打开失败!\n", name2);
exit(EXIT_FAILURE);
}
char ch;
while((ch = getc(in)) && ch != EOF)
putc(ch,out);
fclose(in);
fclose(out);
return 0;
}
test.c
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[]){
char name[40];
char name2[40];
printf("请输入文件名:");
scanf("%s", name);
printf("请输出文件名:");
scanf("%s", name2);
FILE *in,*out;
if((in=fopen(name,"r")) == NULL){
printf("%s 打开失败!\n", name);
exit(EXIT_FAILURE);
}
if((out=fopen(name2,"w"))==NULL){
printf("%s 打开失败!\n", name2);
exit(EXIT_FAILURE);
}
char ch;
while((ch = getc(in)) && ch != EOF)
putc(ch,out);
fclose(in);
fclose(out);
return 0;
}
a.txt
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[]){
char name[40];
char name2[40];
printf("请输入文件名:");
scanf("%s", name);
printf("请输出文件名:");
scanf("%s", name2);
FILE *in,*out;
if((in=fopen(name,"r")) == NULL){
printf("%s 打开失败!\n", name);
exit(EXIT_FAILURE);
}
if((out=fopen(name2,"w"))==NULL){
printf("%s 打开失败!\n", name2);
exit(EXIT_FAILURE);
}
char ch;
while((ch = getc(in)) && ch != EOF)
putc(ch,out);
fclose(in);
fclose(out);
return 0;
}
编写一个程序,按顺序在屏幕上显示命令行中列出的所有文件。使用argc控制循环。
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[]){
for(int i=1;i<argc;++i){
puts(argv[i]);
}
return 0;
}
修改程序清单13.5中的程序,用命令行界面代替交互式界面。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define BUFSIZE 4096
#define SLEN 81
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')continue;
}
}
return ret_val;
}
int main(int argc, char* argv[]){
if(argc<3){
printf("缺少文件,请按照格式输入\n");
exit(EXIT_FAILURE);
}
FILE *fa, *fs;
int files = 0;
char file_app[SLEN];
char file_src[SLEN];
int ch;
if((fa=fopen(argv[1], "a+"))==NULL){
fprintf(stderr, "Can`t open %s \n", file_app);
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[i], file_app) == 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);
continue;
}
append(fs, fa);
if(ferror(fs)!=0) fprintf(stderr, "Error in reading files %s\n", argv[i]);
if(ferror(fa)!= 0)fprintf(stderr, "Error in reading files %s\n", file_app);
fclose(fs);
++files;
printf("File %s appended.\n", argv[i]);
}
}
printf("Done append. %d files appended.\n", files);
rewind(fa);
printf("%s contents: \n", file_app);
while((ch=getc(fa))!=EOF) putchar(ch);
puts("Done displaying.");
fclose(fa);
return 0;
}
a.txt
abc 123 ref 345
dog is running
cat is running
t.cpp
#include
int main(void){
const int i;
return 0;
}
test.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define BUFSIZE 4096
#define SLEN 81
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')continue;
}
}
return ret_val;
}
int main(int argc, char* argv[]){
if(argc<3){
printf("缺少文件,请按照格式输入\n");
exit(EXIT_FAILURE);
}
FILE *fa, *fs;
int files = 0;
char file_app[SLEN];
char file_src[SLEN];
int ch;
if((fa=fopen(argv[1], "a+"))==NULL){
fprintf(stderr, "Can`t open %s \n", file_app);
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[i], file_app) == 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);
continue;
}
append(fs, fa);
if(ferror(fs)!=0) fprintf(stderr, "Error in reading files %s\n", argv[i]);
if(ferror(fa)!= 0)fprintf(stderr, "Error in reading files %s\n", file_app);
fclose(fs);
++files;
printf("File %s appended.\n", argv[i]);
}
}
printf("Done append. %d files appended.\n", files);
rewind(fa);
printf("%s contents: \n", file_app);
while((ch=getc(fa))!=EOF) putchar(ch);
puts("Done displaying.");
fclose(fa);
return 0;
}#include<iostream>
int main(void){
const int i;
return 0;
}#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define BUFSIZE 4096
#define SLEN 81
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')continue;
}
}
return ret_val;
}
int main(int argc, char* argv[]){
if(argc<3){
printf("缺少文件,请按照格式输入\n");
exit(EXIT_FAILURE);
}
FILE *fa, *fs;
int files = 0;
char file_app[SLEN];
char file_src[SLEN];
int ch;
if((fa=fopen(argv[1], "a+"))==NULL){
fprintf(stderr, "Can`t open %s \n", file_app);
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[i], file_app) == 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);
continue;
}
append(fs, fa);
if(ferror(fs)!=0) fprintf(stderr, "Error in reading files %s\n", argv[i]);
if(ferror(fa)!= 0)fprintf(stderr, "Error in reading files %s\n", file_app);
fclose(fs);
++files;
printf("File %s appended.\n", argv[i]);
}
}
printf("Done append. %d files appended.\n", files);
rewind(fa);
printf("%s contents: \n", file_app);
while((ch=getc(fa))!=EOF) putchar(ch);
puts("Done displaying.");
fclose(fa);
return 0;
}
使用命令行参数的程序依赖于用户的内存如何正确地使用它们。重写程序清单13.2中的程序,不适用命令行参数,而是提示用户输入所需信息。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LEN 40
int main(int argc, char*argv[]){
FILE *in, *out;
int ch;
char name[LEN];
int count = 0;
if(argc < 2){
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(EXIT_FAILURE);
}
if((in = fopen(argv[1], "r")) == NULL){
fprintf(stderr, "I can`t open the file %s \n", argv[1]);
exit(EXIT_FAILURE);
}
strncpy(name, argv[1], LEN-5);
strcat(name, ".red");
if((out=fopen(name, "w")) == NULL){
fprintf(stderr, "I can`t open the file %s \n", argv[1]);
exit(EXIT_FAILURE);
}
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;
}
a.txt
dog is running on the grass.
a.txt.red
dog is running on the grass.
编写一个程序打开两个文件。可以使用命令行参数或提示用户输入文件名。
a. 该程序以这样的顺序打印:打印第1个文件第1行,第2个文件第1行,第1个文件的第2行,第2个文件的第2行,以此类推,打印到行数较多文件的最后一行。
b. 修改该程序,把行号相同的行打印成1行。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LEN 40
int main(int argc, char*argv[]){
if(argc<3){
printf("Usage: %s 文件名", argv[0]);
exit(EXIT_FAILURE);
}
FILE *in_1, *in_2;
if((in_1 = fopen(argv[1], "r")) == NULL){
fprintf(stderr, "I can`t open the file %s \n", argv[1]);
exit(EXIT_FAILURE);
}
if((in_2 = fopen(argv[2], "r")) == NULL){
fprintf(stderr, "I can`t open the file %s \n", argv[2]);
exit(EXIT_FAILURE);
}
int ch1=1,ch2=1;
while(ch1 != EOF && ch2 != EOF){
while(((ch1 = getc(in_1))!= '\n') && (ch1 != EOF)) putchar(ch1);
if(ch1 == EOF) {
putchar('\n');
break;
}
if(ch1 == '\n'){
putchar(ch1);
while(((ch2 = getc(in_2))!= '\n') && (ch2 != EOF)) putchar(ch2);
if(ch2 == EOF){
putchar('\n');
break;
}
if(ch2 == '\n') {
putchar(ch2);
continue;
}
}
}
if(ch1 != EOF){
while((ch1 = getc(in_1))!= EOF) putchar(ch1);
}
if(ch2 != EOF){
while((ch1 = getc(in_2))!= EOF) putchar(ch2);
}
return 0;
}
t.txt文档内容
abc 123 ref 345
dog is running
cat is running
cat is running
a.txt文档内容
dog is running on the grass.
aaaa
bbbb
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LEN 40
int main(int argc, char*argv[]){
if(argc<3){
printf("Usage: %s 文件名", argv[0]);
exit(EXIT_FAILURE);
}
FILE *in_1, *in_2;
if((in_1 = fopen(argv[1], "r")) == NULL){
fprintf(stderr, "I can`t open the file %s \n", argv[1]);
exit(EXIT_FAILURE);
}
if((in_2 = fopen(argv[2], "r")) == NULL){
fprintf(stderr, "I can`t open the file %s \n", argv[2]);
exit(EXIT_FAILURE);
}
int ch1=1,ch2=1;
while(ch1 != EOF && ch2 != EOF){
while(((ch1 = getc(in_1))!= '\n') && (ch1 != EOF)) putchar(ch1);
if(ch1 == EOF) {
putchar('\n');
break;
}
if(ch1 == '\n'){
//putchar(ch1);
while(((ch2 = getc(in_2))!= '\n') && (ch2 != EOF)) putchar(ch2);
if(ch2 == EOF){
putchar('\n');
break;
}
}
printf("\n");
}
if(ch1 != EOF){
while((ch1 = getc(in_1))!= EOF) putchar(ch1);
}
if(ch2 != EOF){
while((ch1 = getc(in_2))!= EOF) putchar(ch2);
}
return 0;
}
abc 123 ref 345
dog is running
cat is running
cat is running
a.txt文档内容
dog is running on the grass.
aaaa
bbbb
编写一个程序,以一个字符和任意文件名作为命令行参数。如果字符后面没有参数,该程序读取标准输入,否则,程序依次打开每个文件并报告每个文件中该字符出现的次数。文件名和字符本身也要一同报告。程序应包含错误检查,以确定参数数量是否正确或是否能够打开文件。如果无法打开文件。程序应报告这一情况,然后继续处理下一个文件。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LEN 40
int count_char_num(char *n,char c){
FILE *in;
if((in = fopen(n, "r")) == NULL){
fprintf(stderr, "I can`t open the file %s \n", n);
exit(EXIT_FAILURE);
}
char t;
int num=0;
while((t=getc(in))!=EOF){
if(t == c) ++num;
}
return num;
}
int main(int argc, char*argv[]){
char name[LEN];
if(argc<2) printf("参数不够,请重新输入命令。");
else if(argc<3){
printf("请输入文件名:");
while(scanf("%s", name) == 1){
printf("%s 文件中有 %d 个%c字符\n", name, count_char_num(name, argv[1][0]), argv[1][0]);
while(getchar()!='\n');
}
}else{
for(int i=2;i<argc;++i)printf("%s 文件中有 %d 个%c字符\n", argv[i], count_char_num(argv[i], argv[1][0]), argv[1][0]);
}
return 0;
}
a.txt内容
dog is running on the grass.
aaaa
bbbb
t.txt内容
abc 123 ref 345
dog is running
cat is running
cat is running
修改程序清单13.3中的程序,从1开始,根据加入列表的顺序为每个单词编号。当程序下次运行时,确保新的单词编号接着上次的编号开始。
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[]){
FILE *in,*out;
if((in=fopen(argv[1],"r")) == NULL){
printf("%s 打开失败!\n", argv[1]);
exit(EXIT_FAILURE);
}
if((out=fopen(argv[2],"a+"))==NULL){
printf("%s 打开失败!\n", argv[2]);
exit(EXIT_FAILURE);
}
char w[40];
int num=0;
fseek(out,-(long)sizeof(int), SEEK_END);
if(fscanf(out,"%d",&num)!=1) num=0;
printf("%d\n",num);
fseek(out,0L, SEEK_END);
while(fscanf(in,"%s",w) == 1){
printf("%s\n",w);
fprintf(out,"%s - %d\n",w,++num);
}
fclose(in);
fclose(out);
return 0;
}
a.txt内容
dog is running on the grass.
aaaa
bbbb
运行两次后的t.txt内容
dog - 1
is - 2
running - 3
on - 4
the - 5
grass. - 6
aaaa - 7
bbbb - 8
dog - 9
is - 10
running - 11
on - 12
the - 13
grass. - 14
aaaa - 15
bbbb - 16
编写一个程序打开一个文本文件,通过交互方式获得文件名。通过一个循环,提示用户输入一个文件位置。然后该程序打印从该位置开始到下一个换行符之间的内容。用户输入负数或非数值字符可以结束输入循环。
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[]){
char name[40];
printf("请输入您要处理的文件名:");
scanf("%s", name);
FILE *in;
if((in=fopen(name,"r")) == NULL){
printf("%s 打开失败!\n", name);
exit(EXIT_FAILURE);
}
long loc=0;
char c;
printf("请输入您要处理的位置:");
while((scanf("%ld", &loc) == 1) && (loc >=0)){
fseek(in, loc, SEEK_SET);
while((c=getc(in))!=EOF && c!='\n') putchar(c);
}
fclose(in);
return 0;
}
a.txt内容
dog is running on the grass.
aaaa
bbbb
编写一个程序,接受两个命令行参数。第一个参数是一个字符串,第2个参数是一个文件名。然后该程序查找该文件,打印文件中包含该字符串的所有行。因为该任务是面向行而不是面向字符的,所以要使用fgets而不是getc。使用标准c库函数strstr在每一行中查找指定字符串。假设文件中的所有行都不超过255个字符。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char* argv[]){
if(argc<3){
printf("输入格式错误!");
exit(EXIT_FAILURE);
}
FILE *in;
if((in=fopen(argv[2],"r")) == NULL){
printf("%s 打开失败!\n", argv[2]);
exit(EXIT_FAILURE);
}
char str[256];
while(fgets(str,255,in) != NULL){
if(strstr(str,argv[1])!= NULL){
puts(str);
}
}
fclose(in);
return 0;
}
a.txt内容
dog is running on the grass.
aaaa
bbbb
创建一个文本文件,内含20行,每行30个整数。这些整数都在0~9之间,用空格分开。该文件是用数字表示一张图片,0 ~ 9表示逐渐增加的灰度。编写一个程序,把文件中的内容读入一个2030的int数组中。一种把这些数字转换为图片的粗略方法是:该程序使用数组中的值初始化一个2031的字符数组,用值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 1 9 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<ctype.h>
int main(int argc, char* argv[]){
char file[] = "t.txt";
FILE *in;
if((in=fopen(file,"r")) == NULL){
printf("%s 打开失败!\n", argv[2]);
exit(EXIT_FAILURE);
}
int num[20][30]={0};
int r=0;
int c=0;
char ch;
while((ch=getc(in))!=EOF){
if(isdigit(ch))num[r][c++] = ch-'0';
if(ch=='\n'){
++r;
c=0;
}
}
char label[]={' ', '.', ',', ':', '~', '*', '=', '+', '%', '#'};
for(int i=0;i<20;++i){
for(int j=0;j<30;++j){
putchar(label[num[i][j]]);
}
putchar('\n');
}
fclose(in);
return 0;
}
使用变长数组代替标准数组,完成编程练习12.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
int main(int argc, char* argv[]){
char file[] = "t.txt";
FILE *in;
if((in=fopen(file,"r")) == NULL){
printf("%s 打开失败!\n", argv[2]);
exit(EXIT_FAILURE);
}
int row = 20;
int col = 30;
int num[row][col];
int r=0;
int c=0;
char ch;
while((ch=getc(in))!=EOF){
if(isdigit(ch))num[r][c++] = ch-'0';
if(ch=='\n'){
++r;
c=0;
}
}
char label[]={' ', '.', ',', ':', '~', '*', '=', '+', '%', '#'};
for(int i=0;i<20;++i){
for(int j=0;j<30;++j){
putchar(label[num[i][j]]);
}
putchar('\n');
}
fclose(in);
return 0;
}
数字图像,尤其是从宇宙飞船发回的数字图像,可能会包含一些失真。为编程练习12添加消除失真的函数。该函数把每个值与它上下左右相邻的值作比较,如果该值与其他周围相邻值的差都大于1,则用所有相邻值的平均值(四舍五入)代替该值。注意,与边界上的点相邻的点少于4个,所以做特殊处理。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
int main(int argc, char* argv[]){
char file[] = "t.txt";
FILE *in;
if((in=fopen(file,"r")) == NULL){
printf("%s 打开失败!\n", argv[2]);
exit(EXIT_FAILURE);
}
int row = 20;
int col = 30;
int num[row][col];
int r=0;
int c=0;
char ch;
while((ch=getc(in))!=EOF){
if(isdigit(ch))num[r][c++] = ch-'0';
if(ch=='\n'){
++r;
c=0;
}
}
for(int i=1;i<29;++i){
if(abs(num[0][i-1]-num[0][i])>1 && abs(num[0][i+1]-num[0][i])>1 && abs(num[1][i]-num[0][i])>1)
num[0][i] = (num[0][i-1]+num[0][i+1]+num[1][i])/3;
}
for(int i=1;i<29;++i){
if(abs(num[19][i-1]-num[19][i])>1 && abs(num[19][i+1]-num[19][i])>1 && abs(num[18][i]-num[19][i])>1)
num[19][i] = (num[19][i-1]+num[19][i+1]+num[18][i])/3;
}
for(int i=1;i<19;++i){
if(abs(num[i-1][0]-num[i][0])>1 && abs(num[i+1][0]-num[i][0])>1 && abs(num[i][1]-num[i][0])>1)
num[i][0] = (num[i-1][0]+num[i+1][0]+num[i][1])/3;
}
for(int i=1;i<19;++i){
if(abs(num[i-1][29]-num[i][29])>1 && abs(num[i+1][29]-num[i][29])>1 && abs(num[i][28]-num[i][29])>1)
num[i][29] = (num[i-1][29]+num[i+1][29]+num[i][28])/3;
}
for(int i=1;i<19;++i){
for(int j=1;j<29;++j){
if(abs(num[i-1][j]-num[i][j])>1 && abs(num[i+1][j]-num[i][j])>1 && abs(num[i][j-1]-num[i][j])>1 && abs(num[i][j+1]-num[i][j])>1)
num[i][j] = (num[i-1][j]+num[i+1][j]+num[i][j-1]+num[i][j+1])/4;
}
}
for(int i=0;i<20;++i){
for(int j=0;j<30;++j){
printf("%d",num[i][j]);
}
putchar('\n');
}
char label[]={' ', '.', ',', ':', '~', '*', '=', '+', '%', '#'};
for(int i=0;i<20;++i){
for(int j=0;j<30;++j){
putchar(label[num[i][j]]);
}
putchar('\n');
}
fclose(in);
return 0;
}