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

来源:互联网 发布:酒神淘宝店地址 编辑:程序博客网 时间:2024/05/17 01:51
第一题
#include<stdio.h>
#include<stdlib.h>
const int LEN = 100;
int main(void)
{
char fileName[LEN];
FILE* tarFile;
char ch;

printf("PLease Input File Name:\n");
gets(fileName);

if((tarFile = fopen(fileName,"r")) == NULL)
{
printf("Open %s Fail.",fileName);
exit(1);
}

while((ch = getc(tarFile)) != EOF)
printf("%c",ch);

fclose(tarFile);

return 0;
}

//the `gets' function is dangerous and should not be used.


第二题

#include<stdio.h>
#include<stdlib.h>
int main(int argc , char** argv)
{
FILE* sourceFile;
FILE* tarFile;
char ch;
if(argc != 3) //检查参数
{
printf("参数错误.\n");
exit(1);
}

if((tarFile = fopen(*(argv+1),"w")) == NULL) //打开文件
{
printf("无法打开或创建目标文件%s",*(argv+1));
exit(2);
}
if((sourceFile = fopen(*(argv+2),"r")) == NULL)
{
printf("无法打开源文件%s",*(argv+2));
exit(3);
}

while((ch = getc(sourceFile)) != EOF) //复制文件内容
putc(ch,tarFile);

if(fclose(tarFile) == EOF) //关闭文件
{
printf("文件%s关闭失败.\n",*(argv+1));
exit(4);
}
if(fclose(sourceFile) == EOF)
{
printf("文件%s关闭失败.\n",*(argv+2));
exit(5);
}

return 0;
}


第三题

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
const int LEN = 100;
int main(void)
{
char tarFileName[LEN];
char sourceFileName[LEN];
FILE* tarFile;
FILE* sourceFile;
char ch;

//获取文件名
printf("请输入源文件名:");
scanf("%s",sourceFileName);
printf("请输入目标文件名:");
scanf("%s",tarFileName);

//打开文件
if((sourceFile = fopen(sourceFileName,"r")) == NULL)
{
printf("文件%s无法打开.",sourceFileName);
exit(1);
}
if((tarFile = fopen(tarFileName,"w")) == NULL)
{
printf("文件%s无法创建.",tarFileName);
exit(2);
}

//复制文件内容
while((ch = getc(sourceFile)) != EOF)
putc(ch,tarFile);


if(fclose(tarFile) == EOF) //关闭文件
{
printf("文件%s关闭失败.\n",tarFileName);
exit(3);
}
if(fclose(sourceFile) == EOF)
{
printf("文件%s关闭失败.\n",sourceFileName);
exit(4);
}

return 0;
}


第四题

#include<stdio.h>
#include<stdlib.h>
const int MAX = 5; //最多5个文件
int main(int argc , char** argv)
{
FILE* tarFile;
char ch;
//参数检查
if(argc > MAX || argc == 1)
{
printf("错误的参数.");
exit(1);
}

//循环显示文件内容
for(int i = 1 ; i < argc ; ++i)
{
if((tarFile = fopen(*(argv+i),"r")) == NULL) //打开文件
{
printf("文件%s打开失败.",*(argv+i));
exit(2);
}
printf("~~~~~~%s~~~~~~~\n",*(argv+i)); //显示文件
while((ch = getc(tarFile)) != EOF)
putc(ch,stdout);
if(fclose(tarFile) == EOF) //关闭文件
{
printf("文件%s关闭失败.",*(argv+i+1));
exit(3);
}
}

return 0;
}


第五题

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
const int MAX = 10; //最多拼接10个文件
int main(int argc , char** argv)
{
FILE* fileNames[argc-1];
char chs;
char openType;
if(argc > MAX+1 || argc < 3) //检测参数
{
printf("参数错误.");
exit(1);
}

for(int i = 2 ; i < argc ; ++i) //检查追加文件和目标文件是否相同
{
if(strcmp(*(argv+1),*(argv+i)) == 0)
{
printf("无法拼接源文件.");
exit(2);
}
}

for(int i = 1,j = 0 ; i < argc ; ++i,++j) //打开文件
{
if(i == 1)
openType = 'a';
else openType = 'r';
if((fileNames[j] = fopen(*(argv+i),&openType)) == NULL)
{
printf("文件%s打开失败.",*(argv+i));
exit(3);
}
}

for(int i = 1 ; i < argc-1 ; ++i) //拼接
{
while((chs = getc(fileNames[i])) != EOF)
putc(chs,fileNames[0]);
}

for(int i = 0 ; i < argc-1 ; ++i) //关闭文件
{
if(fclose(fileNames[i]) == EOF)
{
printf("文件%s关闭失败.",*(argv+i+1));
exit(4);
}
}

return 0;
}



第六题

#include<stdio.h>
#include<stdlib.h>
const int LEN = 100;
const int RLevel = 3;
int main(void)
{
char sourceFileName[LEN];
FILE* sourceFile;
char tarFileName[LEN];
FILE* tarFile;
char chs;

printf("请输入需要压缩的文件名:"); //获取文件名
gets(sourceFileName);
if((sourceFile = fopen(sourceFileName,"r")) == NULL)
{
printf("无法打开源文件.");
exit(1);
}

printf("请输入压缩文件名:");
gets(tarFileName);
if((tarFile = fopen(tarFileName,"w")) == NULL)
{
printf("无法创建文件%s",tarFileName);
exit(2);
}

for(int i = 1 ; ; ++i) //压缩
{
if(((chs = getc(sourceFile)) != EOF) && i%RLevel == 0)
putc(chs,tarFile);
if(chs == EOF)
break;
}

if(fclose(sourceFile) == EOF) //关闭文件
{
printf("文件%s关闭失败.",sourceFileName);
exit(3);
}
if(fclose(tarFile) == EOF)
{
printf("文件%s关闭失败.",tarFileName);
exit(4);
}

printf("压缩完成.\n");
return 0;
}


第七题A部分

#include<stdio.h>
#include<stdlib.h>
const char lineEnd = '\n'; //这个是linux的换行符,其他系统换成系统对应的换行符号
int main(int argc , char** argv)
{
FILE* file_1;
FILE* file_2;
char chs_1;
char chs_2;
int hasEnd = 0;
if(argc != 3) //检查参数
{
printf("参数错误.");
exit(1);
}

if((file_1 = fopen(*(argv+1),"r")) == NULL) //打开文件
{
printf("文件%s打开失败.",*(argv+1));
exit(2);
}
if((file_2 = fopen(*(argv+2),"r")) == NULL)
{
printf("文件%s打开失败.",*(argv+2));
exit(3);
}

for(int i = 0 ; ; ++i) //输出
{
while(1)
{
chs_1 = getc(file_1);
if(chs_1 == EOF)
break;
putc(chs_1,stdout);
if(chs_1 == lineEnd)
break;
}
while(1)
{
chs_2 = getc(file_2);
if(chs_2 == EOF)
break;
putc(chs_2,stdout);
if(chs_2 == lineEnd)
break;
}
if(chs_1 == EOF && chs_2 == EOF)
break;
}

if(fclose(file_1) == EOF) //关闭文件
{
printf("文件%s关闭失败.",*(argv+1));
exit(4);
}
if(fclose(file_2) == EOF)
{
printf("文件%s关闭失败.",*(argv+2));
exit(5);
}

return 0;
}

第七题B部分

#include<stdio.h>
#include<stdlib.h>
const char lineEnd = '\n'; //这个是linux的换行符,其他系统换成系统对应的换行符号
int main(int argc , char** argv)
{
FILE* file_1;
FILE* file_2;
char chs_1;
char chs_2;
int hasEnd = 0;
if(argc != 3) //检查参数
{
printf("参数错误.");
exit(1);
}

if((file_1 = fopen(*(argv+1),"r")) == NULL) //打开文件
{
printf("文件%s打开失败.",*(argv+1));
exit(2);
}
if((file_2 = fopen(*(argv+2),"r")) == NULL)
{
printf("文件%s打开失败.",*(argv+2));
exit(3);
}

for(int i = 0 ; ; ++i) //输出
{
while(1)
{
chs_1 = getc(file_1);
if(chs_1 == EOF)
break;
if(chs_1 == lineEnd)
break;
putc(chs_1,stdout);
}
while(1)
{
chs_2 = getc(file_2);
if(chs_2 == EOF)
break;
if(chs_2 == lineEnd)
break;
putc(chs_2,stdout);
}
putc(lineEnd,stdout); //和13-7-1相比,不同在于不出书源文件的换行符,而是每隔两行输出一个换行号
if(chs_1 == EOF && chs_2 == EOF)
break;
}

if(fclose(file_1) == EOF) //关闭文件
{
printf("文件%s关闭失败.",*(argv+1));
exit(4);
}
if(fclose(file_2) == EOF)
{
printf("文件%s关闭失败.",*(argv+2));
exit(5);
}

return 0;
}



第八题

#include<stdio.h>
#include<stdlib.h>
const int Max = 5; //最多检查5个文件
int countChar(FILE* files , char ch);
int main(int argc , char** argv)
{
int fileCounts = argc - 2;
FILE* fileName[fileCounts];
if(argc < 3 || argc > Max + 2) //检查参数
{
printf("参数错误.");
exit(1);
}
//问题1 干参数的获取必须在检查参数(argc>3)完成后才能获取,否则会出现段错误
const char pointChar = *(*(argv+1)); //程序的第二个参数不管你输入多少字符,程序都之检查地一个字符出现的次数

for(int i = 0 ; i < fileCounts ; ++i) //打开文件
{
if((fileName[i] = fopen(*(argv+i+2),"r")) == NULL)
{
printf("文件%s打开失败.",*(argv+i+2));
exit(2);
}
}

for(int i = 0 ; i < fileCounts ; ++i) //计数
printf("文件%s出现字符%c总共%d次.\n",*(argv+2+i),pointChar,countChar(fileName[i],pointChar));

for(int i = 0 ; i < fileCounts ; ++i)
{
if(fclose(fileName[i]) == EOF)
{
printf("文件%s关闭失败.",*(argv+i+2));
exit(3);
}
}

return 0;
}
int countChar(FILE* files , char ch) //问题2 这里传递参数FILE*不能传递 const FILE*,原因不详..
{
char chs;
int counts = 0;
while((chs = getc(files)) != EOF)
{
if(chs == ch)
++counts;
}
return counts;
}


第九题

#include<stdio.h>
#include<stdlib.h>
const int Len = 100;
int main(int argc , char** argv)
{
FILE* files;
char words[Len];
if(argc != 2)//检查参数
{
printf("参数错误.");
exit(1);
}

if((files = fopen(*(argv+1),"a+")) == NULL) //打开文件
{
printf("无法打开文件%s.",*(argv+1));
exit(2);
}

printf("请输入单词:"); //单词输出和输出
while(gets(words) != NULL && words[0] != '\0')
fprintf(files,"%s",words);
rewind(files); //完成输入并返回文件起始位置
puts("文件内容为:\n");
while(fscanf(files,"%s",words) == 1)
puts(words);

if(fclose(files) == EOF) //关闭文件
{
printf("文件%s关闭失败.",*(argv+1));
exit(3);
}

return 0;
}


第十题

#include<stdio.h>
#include<stdlib.h>
const int LEN = 100;
const char lineEnd = '\n';
int main(void)
{
FILE* files;
long len;
long beginAddress;
char fileName[LEN];
char chs;
printf("请输入文件名:");
gets(fileName);
if((files = fopen(fileName,"r")) == NULL) //获取文件名并打开文件
{
printf("文件%s无法打开.",fileName);
exit(1);
}

fseek(files,0L,SEEK_END); //获取文件长度
len =ftell(files);

for(int i = 0 ; ; ++i) //输出文件内容
{
printf("请输入起始位置:");
if(scanf("%ld",&beginAddress) && (beginAddress < len))
{
fseek(files,beginAddress,SEEK_SET);
do
{
chs = getc(files);
putc(chs,stdout);
}while(chs != EOF && chs != lineEnd);
}
else break;
}

return 0;
}
 


第十一题

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
const int LEN = 100;
const char lineEnd = '\n'; //linux的换行符
int main(int argc , char** argv)
{
FILE* files;
char chs;
char lineChar[LEN];

if(argc != 3) //检查参数
{
printf("参数错误.");
exit(1);
}

if((files = fopen(*(argv+2),"r")) == NULL) //打开文件
{
printf("文件%s打开失败.",*(argv+2));
exit(1);
}

for(int i = 0 ; ; ++i)
{
for(int j = 0 ; ; ++j) //该嵌套循环用于读取每一行
{
chs = getc(files);
if(chs != lineEnd && chs != EOF)
lineChar[j] = chs;
else break;
}
if(chs == EOF)
break;
if(strstr(lineChar,*(argv+1)))
printf("%s\n",lineChar);
memset(lineChar,0,LEN); //清楚字符串函数
}
}


第十二题

#include<stdio.h>
#include<stdlib.h>
const int columns = 30;
const int rows = 20;
const char lineEnd = '\n';
int main(int argc , char** argv)
{
FILE* diagitFile;
FILE* pixFile;
int source[rows][columns];
char chs;

if(argc != 3) //参数错误
{
printf("参数错误.");
exit(1);
}

if((diagitFile = fopen(*(argv+1),"r")) == NULL) //打开文件
{
printf("文件%s打开失败.",*(argv+1));
exit(2);
}
if((pixFile = fopen(*(argv+2),"w")) == NULL)
{
printf("文件%s打开或创建失败.",*(argv+2));
exit(3);
}

for(int i = 0 ; ; ++i) //这个双重循环读取数据,文件*(argv+1)中的数据必须row >= 20,column >= 30,否则会出现段错误
{
if(i >= rows)
break;
for(int j = 0 ; ; ++j)
{
chs = getc(diagitFile);
if(chs == lineEnd)
break;
if(j >= columns)
continue;
source[i][j] = (int)chs - 48; //把字符char转换为数字int,
}
}

for(int i = 0 ; i < rows ; ++i) //输出图像到文件
{
for(int j = 0 ; j < columns ; ++j)
{
switch(source[i][j]) //方便debug这里用字母代替图像
{
case 0:putc('a',pixFile);
break;
case 1:putc('b',pixFile);
break;
case 2:putc('c',pixFile);
break;
case 3:putc('d',pixFile);
break;
case 4:putc('e',pixFile);
break;
case 5:putc('f',pixFile);
break;
case 6:putc('g',pixFile);
break;
case 7:putc('h',pixFile);
break;
case 8:putc('i',pixFile);
break;
case 9:putc('j',pixFile);
break;
}
}
putc('\n',pixFile);
}

if(fclose(diagitFile) == EOF) //关闭文件
{
printf("文件%s关闭失败.",*(argv+1));
exit(4);
}
if(fclose(pixFile) == EOF)
{
printf("文件%s关闭失败.",*(argv+2));
exit(5);
}

return 0;
}

0 0