您的位置:首页 > 其它

《C Primer Plus(第五版)中文版》第13章第1至13题

2015-08-25 20:53 543 查看
/*
* 1.修改程序清单13.1中的程序,使之不采用命令行参数,而是请求用户输入文件名并读入用户响应,。
*/
#include <stdio.h>
#include <stdlib.h>

int main(void){
int ch;
char inch[20] = {0};
long int count = 0;
FILE * fp;
printf("请输入你要统计的文件名称:\n");
scanf("%s",inch);
fp = fopen(inch,"r");
if(fp == NULL) {
puts("这个文件不存在.");
exit(1);
}
while((ch=getc(fp)) !=EOF){
putc(ch,stdout);
count++;
}
fclose(fp);
printf("这个文件中%ld个字符",count);
return 0;
}
/*
* 2.编写一个文件复制程序,程序需要从命令行获得源文件名和目的文件名,尽可能使用标准I/O和二进制模式
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char *argv[]){
char buf[1024] = {0};
int s = 0;
FILE * fp01; //sources file
FILE * fp02; //target file

if(argc != 3){
printf("输入错误:\n");
printf("例如:test.exe 1.txt 2.txt\n");
exit(1);
}

if((fp01 = fopen(argv[1],"rb")) == NULL){
printf("不能打开%s文件\n",argv[1]);
exit(1);
}

fp02 = fopen(argv[2],"wb");
while(!feof(fp01)){
memset(buf,0,sizeof(buf));
size_t res = fread(buf,sizeof(char),sizeof(buf),fp01);
fwrite(buf,sizeof(char),res,fp02);
s += res;
printf("复制%d字节\n",s);
}
fclose(fp01);
fclose(fp02);
printf("Done");
return 0;
}
/*
* 3.编写一个文件复制程序,提示用户输入源文件名和目的文件名,尽可能使用标准I/O和二进制模式
* 在向输出文件写入时,程序应当使用cype.h中的toupper()函数将所有的文本转换为大写。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(int argc,char *argv[]){
char buf = 0;
int s = 0;
FILE * fp01; //sources file
FILE * fp02; //target file
char f01[20] = { 0 };
char f02[20] = { 0 };

printf("请输入源文件名称:\n");
scanf("%s",f01);
printf("请输入目标文件名称:\n");
scanf("%s",f02);

if((fp01 = fopen(f01,"r")) == NULL){
printf("不能打开%s文件\n",f01);
exit(1);
}

fp02 = fopen(f02,"w");
while((buf = fgetc(fp01)) != EOF){
fputc(toupper(buf),fp02);
s++;
printf("复制%d字符\n",s);
}
fclose(fp01);
fclose(fp02);
printf("Done");
return 0;
}


/*
* 4.编写一个程序,依次在屏幕上显示命令行中列出的全部文件,使用argc控制循环。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc,char *argv[]){
char ch;
if(argc  < 2){
printf("No file!\n");
exit(1);
}

for(int i = 1;i<argc;i++){
FILE * fp = fopen(argv[i],"r");
printf("show file %d:%s\n",i,argv[i]);
puts("-------------------------------");
while((ch = fgetc(fp))!= EOF){
putchar(ch);
}
puts("\n-------------------------------");
fclose(fp);
}
printf("Done");
return 0;
}


/*
* 5.修改程序清单13.6中的程序,使用命令行参数(而不是交互式界面)获得文件名
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFSIZE 1024
#define SLEN 81
void append(FILE *source,FILE *dest);
int main(int argc,char *argv[]){
FILE *fa,*fs;
int files = 0;
char file_app[SLEN];
char file_src[SLEN];
if(argc < 3){
printf("命令行中的文件数量必须>=2。\n");
exit(2);
}
//file_app = argv[argc-1];
strcpy(file_app,argv[argc-1]);

if((fa = fopen(file_app,"a")) == NULL){
fprintf(stderr,"Can't open %s.\n",file_app);
exit(2);
}
if(setvbuf(fa,NULL,_IOFBF,BUFSIZE) != 0){
fputs("Can't create output buffer\n",stderr);
exit(3);
}
for(int i= 1;i < argc-1;i++){
//file_src = argv[i];
strcpy(file_src,argv[i]);
if(strcmp(file_src,file_app) == 0){
fputs("Can't append file to itself\n",stderr);
}else if((fs = fopen(file_src,"r")) == NULL){
fprintf(stderr,"Can't open %s.",file_src);
}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 file %s.\n",file_src);
if(ferror(fa) != 0)
fprintf(stderr,"Error in reading file %s.\n",file_app);
fclose(fs);
printf("File %s appended.\n",file_src);
files++;
}
}
printf("Done, %d files appended.\n",files);
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);
}


/*
* 6.重写程序清单13.2中的程序,不使用命令行参数,而是提示用户输入所需要的信息
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LEN 40

int main(void){
FILE *in,*out;
int ch;
char name1[LEN] = {0};
char name2[LEN] = {0};
int count = 0;

printf("请输入将要压缩的文件名称:\n");
scanf("%s",name1);
if((in = fopen(name1,"r")) == NULL){
fprintf(stderr,"不能打开%s文件\n",name1);
exit(1);
}
strcpy(name2,name1);
strcat(name2,".red");
if((out = fopen(name2,"w")) == NULL){
fprintf(stderr,"不能打开%s文件\n",name2);
exit(2);
}
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;
}
<pre name="code" class="cpp">/*
* 7.编写一个打开两个文件的程序,可以使用命令行参数或者请求用户输入来获得文件名。
* a.让程序打印第一个文件的第一行,第二个文件的第一行,第一个文件的第二行,第二个文件的第二行,依此类推,
* 直到打印完行数较多的的文件的最后一行。
* b.修改程序,把行号相同的行打印到同一行上。
* test.exe <file1> <file2> <a|b>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void del_li(char *s); //删除换行符

int main(int argc,char *argv[]){
char mode = 'a';
char name01[20] = {0};
char name02[20] = {0};
char row[100] = {0};
FILE *fp1,*fp2;
if(argc <= 1){
printf("请输入文件一名称:\n");
scanf("%s",name01);
printf("请输入文件二名称:\n");
scanf("%s",name02);
}else if(argc == 2){
strcpy(name01,argv[1]);
printf("请输入文件二名称:\n");
scanf("%s",name02);
}else if(argc == 4){
strcpy(name01,argv[1]);
strcpy(name02,argv[2]);
mode = argv[3][0];
}

fp1 = fopen(name01,"r");
fp2 = fopen(name02,"r");
while(!feof(fp1) || !feof(fp2)){

if(!feof(fp1)){
memset(row,0,sizeof(row));
fgets(row,sizeof(row),fp1);
if(mode == 'b')
del_li(row);
printf("%s",row);
}
if(!feof(fp2)){
memset(row,0,sizeof(row));
fgets(row,sizeof(row),fp2);
if(mode == 'b')
del_li(row);
printf("%s",row);
}
if(mode == 'b')
printf("\n");
}
fclose(fp1);
fclose(fp2);
return 0;
}

void del_li(char *s){
char * i;
if((i = strchr(s,'\n')) != NULL)
*i = 0;
}
/*
* 8.编写一个程序,将一个字符、零个或多个文件名作为命令行参数。如果字符后没有参数跟随,程序读取标准输入文件,否则
* ,程序依次打开每个文件,然后报告每个文件中该字符出现数。文件名与该字符本身也与计数值一起报告。程序中包含错误检查
* ,以确定参数的数目是否正确和是否能打开文件,如果不能打开,程序要报告这一情况,然后转入处理下一个文件。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define COLS 81
unsigned int count(FILE *fp, char ch); //统计fp文件中ch字符的个数

int main(int argc, char *argv[]) {
FILE *fp;
char ch;
char name[COLS];
if (argc <= 2) {
if (argc == 1) {
printf("请输入要统计的字符:");
scanf("%c", &ch);
} else
ch = argv[1][0];
printf("请输入要统计的文件名称:\n");
while (scanf("%s", name) != 0) {
if (strcmp(name, "exit") == 0)
break;
fp = fopen(name, "r");
if (fp == NULL) {
fprintf(stderr, "文件%s打开失败.\n", name);
} else {
fprintf(stdout, "文件%s包含%u个%c字符\n", name, count(fp, ch), ch);
}
fclose(fp);
printf("请输入要统计的文件名称:\n");
}
} else if (argc > 2) {
ch = argv[1][0];
for (int i = 2; i < argc; i++) {
fp = fopen(argv[i], "r");
if (fp == NULL) {
fprintf(stderr, "文件%s打开失败.\n", argv[i]);
} else {
fprintf(stdout, "文件%s包含%u个%c字符\n", argv[i], count(fp, ch), ch);
}
fclose(fp);
}
}
return 0;
}

unsigned int count(FILE *fp, char ch) {
unsigned int i = 0;
char dch;
while ((dch = fgetc(fp)) != EOF) {
if (dch == ch)
i++;
}
return i;
}


/*
* 9.修改程序清单13.3中的程序,从1开始,根据加入列表的顺序为每个单词编号,当再次运行程序时,确保新的单词编号接着前面的编号开始。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
int main(void){
int n = 0;
char ch;
FILE * fp;
char words[MAX];
if((fp = fopen("words.txt","a+")) == NULL){
fprintf(stdout,"Can't open \"words\" files.\n");
exit(1);
}
puts("Enter words to add to the files:press the Enter");
puts("key at the begining of a line to terminate.");
/*while(gets(words) != NULL && words[0] != '\0'){
fprintf(fp,"%s ",words);
}*/
long int i= 0;
while(fseek(fp,i,SEEK_END) ==0){
ch = getc(fp);
if(ch==':') break;
i--;
}
i=0;
while(fseek(fp,i,SEEK_CUR) == 0){
ch = getc(fp);
if(ch==' ') break;
i--;
}
if(fscanf(fp,"%s",words) == 1){
n = atoi(words);
}
fseek(fp,0L,SEEK_END);
while(scanf("%s",words) == 1){
if(strcmp(words,"exit") == 0 ) break;
n++;
fprintf(fp,"%d:%s ",n,words);
memset(words,0,sizeof(words));
fflush(fp);
}
puts("File contents:");
rewind(fp);
while(fscanf(fp,"%s",words) == 1)
puts(words);
if(fclose(fp) != 0)
fprintf(stderr,"Error closing file\n");
return 0;
}


/*
* 10.编写一个程序,打开一个文本文件,文件名通过交互方式获得,建立一个循环,请求用户输入一个文件位置,然后程序打印
* 文件中从该位置开始到下一换行符之间的部份,用户通过输入非数字字符来终止输入循环。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
long int filesize(FILE *fp);
int main(void) {
long int lines = 0;
char name[MAX] = { 0 };
FILE *fp;
printf("Enter file name:");
gets(name);
if ((fp = fopen(name, "r")) == NULL) {
fprintf(stderr, "Can't open %s file.", name);
exit(1);
}

printf("Enter line number:");
while (scanf("%ld", &lines) != 0) {
if (lines < filesize(fp)) {
if (fseek(fp, lines, SEEK_SET) == 0) {
memset(name, 0, sizeof(name));
fgets(name, MAX, fp);
fprintf(stdout, "%s\n", name);
}
} else {
fprintf(stdout, "can't find line number:%ld\n", lines);
}
printf("Enter line number(exit q):");
}
if (fclose(fp) != 0) {
fprintf(stderr, "Error in closing files\n");
exit(2);
}
return 0;
}
long int filesize(FILE *fp) {
long int s = 0;
fseek(fp, 0L, SEEK_END);
s = ftell(fp);
rewind(fp);
return s;
}
/*
* 11.编写一个程序,接受两个命令行参数,第一个参数为一个字符串,第二个为文件名,程序打印文件中包含该字符串的
* 所有行。因为这一个任务是面向行而不是面行字符的,所以要使用fgets(),而不是getc(),使用标准C库函数strstr()
* 在每一行中搜索这一字符串
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100

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

char buf[MAX] = { 0 };
FILE *fp;
if(argc < 3 || argc > 3){
fprintf(stderr, "Error input.\n");
exit(1);
}
if((fp = fopen(argv[2],"r")) == NULL){
fprintf(stderr, "Can't open %s file.\n",argv[2]);
exit(2);
}
printf("find:%s,file:%s\n",argv[1],argv[2]);
while(!feof(fp)){
memset(buf,0,sizeof(buf));
fgets(buf,MAX,fp);
if(strstr(buf,argv[1]) != NULL)
printf("%s",buf);
}
if (fclose(fp) != 0) {
fprintf(stderr, "Error in closing files\n");
exit(3);
}
return 0;
}


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

#define ROW 20  //数组行数
#define CLO 30  //数组列数

char itoc(int s); //将s转换为指定的字符
int main(int argc,char * argv[]) {
int num = 0;
int image[ROW][CLO] = { 0 };
char imagechar[ROW][CLO+1] = {0};
FILE *fp = fopen("1.txt","r");
FILE *fp1 = fopen("2.txt","w");

for(int i=0;i<ROW;i++){
for(int j=0;j<CLO;j++){
fscanf(fp,"%d",&num);
image[i][j] = num;
imagechar[i][j] = itoc(num);
printf("%c",imagechar[i][j]);
}
imagechar[i][CLO] = '\n';
fprintf(fp1,"%s",&imagechar[i]);
printf("\n");
}
fclose(fp);
fclose(fp1);
return 0;
}

char itoc(int s){
char chs[10] = " .'=%@*$#t";
return chs[s];
}


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 1
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 1
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


/*
* 13.数字图像,尤其是从宇宙飞船发回的数字图像可能会包含尖峰脉冲,为第12道编程练习题添加消除尖峰脉冲的函数,该函数应该将每一值和它上下左右相邻的值比较,
* 如果该值与它周围每个值的差都大于1,就用所有相邻值的平均值(取与其最接近的整数)取代这个值。注意到边界上的点相邻点少于4个所以它需要特殊处理。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define ROW 20  //数组行数
#define CLO 30  //数组列数

char itoc(int s); //将s转换为指定的字符
void xiao(int row,int clo,int image[row][clo]);
int y4(int n,int tt
); //如果所有元素都大于等于1,如果大于则返回1,否则返回0
int main(int argc, char * argv[]) {
int num = 0;
int image[ROW][CLO] = { 0 };
char imagechar[ROW][CLO + 1] = { 0 };
FILE *fp = fopen("1.txt", "r");
FILE *fp1 = fopen("2.txt", "w");
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < CLO; j++) {
fscanf(fp, "%d", &num);
image[i][j] = num;
imagechar[i][j] = itoc(num);
printf("%c", imagechar[i][j]);
}
imagechar[i][CLO] = '\n';
fprintf(fp1, "%s", &imagechar[i]);
printf("\n");
}
fclose(fp);
fclose(fp1);
printf("\n\n-----图像尖峰处理------\n\n");
FILE *fp4 = fopen("3.txt", "w");
//对图像进行尖峰处理
xiao(ROW, CLO, image);
memset(imagechar,0,sizeof(imagechar));
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < CLO; j++) {
//printf("%d",image[i][j]);
imagechar[i][j] = itoc(image[i][j]);
//printf("%c", imagechar[i][j]);
}
imagechar[i][CLO] = '\n';
fprintf(fp4, "%s", &imagechar[i]);
//printf("\n");
printf("%s",imagechar[i]);
}

fclose(fp4);
return 0;
}

char itoc(int s){
char chs[10] = " .'=%@*$#t";
return chs[s];
}
void xiao(int row,int clo,int image[row][clo]){
int i = 0;
int j = 0;
int temp[4] = {0}; //存放与上下左右相减的绝对值
for(i=0;i<row;i++){
for(j=0;j<clo;j++){
if(i == 0){
if(j==0){
temp[0] = abs(image[i][j]-image[i+1][j]); //下值
temp[1] =  abs(image[i][j]-image[i][j+1]); //右值
if(y4(2,temp)) image[i][j] = (image[i+1][j] + image[i][j+1])/2; //矩阵的左上角
}else if(j==clo-1){
temp[0] = abs(image[i][j]-image[i][j-1]); //左值
temp[1] =  abs(image[i][j]-image[i+1][j]); //下值
if(y4(2,temp)) image[i][j] = (image[i][j-1] + image[i+1][j])/2; //矩阵的右上角
}else{
//矩阵上边
temp[0] = abs(image[i][j]-image[i][j-1]); //左值
temp[1] =  abs(image[i][j]-image[i][j+1]); //右值
temp[2] =  abs(image[i][j]-image[i+1][j]); //下值
if(y4(3,temp)) image[i][j] = (image[i][j-1] + image[i][j+1] + image[i+1][j])/3; //矩阵的上条边
}
}else if(i == row - 1){
if(j == 0){
temp[0] = abs(image[i][j]-image[i-1][j]); //上值
temp[1] =  abs(image[i][j]-image[i][j+1]); //右值
if(y4(2,temp)) image[i][j] = (image[i-1][j] + image[i][j+1])/2; //矩阵的左下角
}else if(j==clo-1){
temp[0] = abs(image[i][j]-image[i][j-1]); //左值
temp[1] =  abs(image[i][j]-image[i-1][j]); //上值
if(y4(2,temp)) image[i][j] = (image[i][j-1] + image[i-1][j])/2; //矩阵的右下角
}else{
//矩阵下边
temp[0] = abs(image[i][j]-image[i][j-1]); //左值
temp[1] =  abs(image[i][j]-image[i][j+1]); //右值
temp[2] =  abs(image[i][j]-image[i-1][j]); //上值
if(y4(3,temp)) image[i][j] = (image[i][j-1] + image[i][j+1] + image[i-1][j])/3; //矩阵的下条边
}
}else if(j==0){
temp[0] = abs(image[i][j]-image[i-1][j]); //上值
temp[1] =  abs(image[i][j]-image[i+1][j]); //下值
temp[2] =  abs(image[i][j]-image[i][j+1]); //右值
if(y4(3,temp)) image[i][j] = (image[i-1][j] + image[i+1][j] + image[i][j+1])/3; //矩阵的左条边
}else if(j==clo-1){
temp[0] = abs(image[i][j]-image[i-1][j]); //上值
temp[1] =  abs(image[i][j]-image[i+1][j]); //下值
temp[2] =  abs(image[i][j]-image[i][j-1]); //左值
if(y4(3,temp)) image[i][j] = (image[i-1][j] + image[i+1][j] + image[i][j-1])/3; //矩阵的右条边
}else{
temp[0] = abs(image[i][j]-image[i-1][j]); //上值
temp[1] =  abs(image[i][j]-image[i+1][j]); //下值
temp[2] =  abs(image[i][j]-image[i][j-1]); //左值
temp[3] =  abs(image[i][j]-image[i][j+1]); //右值
if(y4(4,temp)) image[i][j] = (image[i-1][j] + image[i+1][j] + image[i][j-1] +image[i][j+1])/4; //矩阵内部
}
}
}
}
int y4(int n,int tt
){
for(int i=0;i<n;i++){
if(tt[i] <= 1) return 0;
}
return 1;
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: