《C Primer Plus》(第6版)编程练习——第13章

本章练习中,所有通过交互方式获得文件名的过程都采用scanf()函数获取字符串的形式,其实仅仅为了代码简洁,但并不严谨。比如文件名中有空格,将会达不到预期效果。解决方法是:定义一个11章中的s_gets()函数,并用它来获取文件名。函数定义如下:

char* s_gets(char* st, int n)
{
	char* ret_val;
	int i = 0;

	ret_val = fgets(st, n, stdin);
	if (ret_val)
	{
		while (st[i] != '\n' && st[i] != '\0')
			i++;
		if (st[i] == '\n')
			st[i] = '\0';
		else
			while (getchar() != '\n')
				continue;
	}

	return ret_val;
}

第1题

#include <stdio.h>
#include <stdlib.h>
#define LEN 41

int main(void)
{
	int ch;
	char file[LEN];
	FILE* fp;
	unsigned long count = 0;

	printf("Enter the filename:\n");
	scanf("%40s", file);
	if ((fp = fopen(file, "r")) == NULL)
	{
		fprintf(stderr, "Can't open %s\n", file);
		exit(EXIT_FAILURE);
	}
	while ((ch = getc(fp)) != EOF)
	{
		putc(ch, stdout);
		count++;
	}
	fclose(fp);
	printf("File %s has %lu characters\n", file, count);

	return 0;
}

第2题

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
	int ch;
	FILE* source;
	FILE* target;

	if (argc != 3)
	{
		printf("Usage: %s sourcefile targetfile\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	if ((source = fopen(argv[1], "rb")) == NULL)
	{
		printf("Could not open %s for input\n", argv[1]);
		exit(EXIT_FAILURE);
	}
	if ((target = fopen(argv[2], "wb")) == NULL)
	{
		printf("Could not open %s for output\n", argv[2]);
		exit(EXIT_FAILURE);
	}
	while ((ch = getc(source)) != EOF)
		putc(ch, target);
	if (fclose(source) != 0)
		printf("Could not close file %s\n", argv[1]);
	if (fclose(target) != 0)
		printf("Could not close file %s\n", argv[2]);

	return 0;
}

第3题

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define LEN 41
#define SIZE 4096

int main(void)
{
	char file[LEN];
	char temp[SIZE];
	int ch;
	int i = 0;
	int ct;
	FILE* fp;

	printf("Enter the filename:\n");
	scanf("%40s", file);
	if ((fp = fopen(file, "r")) == NULL)
	{
		fprintf(stderr, "Could not open %s for input.\n", file);
		exit(EXIT_FAILURE);
	}
	while ((ch = getc(fp)) != EOF)
		temp[i++] = toupper(ch);
	ct = i;
	fclose(fp);
	if ((fp = fopen(file, "w")) == NULL)
	{
		fprintf(stderr, "Could not open %s for output.\n", file);
		exit(EXIT_FAILURE);
	}
	for (i = 0; i < ct; i++)
		putc(temp[i], fp);
	fclose(fp);
	printf("Done.\n");

	return 0;

第4题

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
	int i;
	int ch;
	FILE* fp;

	if (argc < 2)
	{
		fprintf(stderr, "Usage: %s file1 file2 ...\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	for (i = 1; i < argc; i++)
	{
		if ((fp = fopen(argv[i], "r")) == NULL)
		{
			fprintf(stderr, "Could not open %s\n", argv[i]);
			continue;
		}
		while ((ch = getc(fp)) != EOF)
			putchar(ch);
		fclose(fp);
	}

	return 0;
}

第5题

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 4096
void append(FILE* source, FILE* dest);

int main(int argc, char* argv[])
{
	FILE* fa;
	FILE* fs;
	int i;
	int files = 0;
	int ch;

	if (argc < 3)
	{
		fprintf(stderr, "Usage: %s appendfile sourcefile[s]\n", argv[0]);
		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 (i = 2; i < argc; i++)
	{
		if (strcmp(argv[i], argv[1]) == 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 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);
}

第6题

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 41

int main(void)
{
	FILE* in;
	FILE* out;
	char in_name[LEN];
	char out_name[LEN];
	int ch;
	int count = 0;

	printf("Enter the filename you want to compress: ");
	scanf("%40s", in_name);
	if ((in = fopen(in_name, "r")) == NULL)
	{
		fprintf(stderr, "I couldn't open the file \"%s\"\n", in_name);
		exit(EXIT_FAILURE);
	}
	strncpy(out_name, in_name, LEN - 5);
	out_name[LEN - 5] = '\0';
	strcat(out_name, ".red");
	if ((out = fopen(out_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题

// 7a 方式一:使用命令行参数
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
	FILE* fp1;
	FILE* fp2;
	char ch1;
	char ch2;
	
	if (argc != 3)
	{
		fprintf(stderr, "Usage: %s filename1 filename2\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	if ((fp1 = fopen(argv[1], "r")) == NULL)
	{
		fprintf(stderr, "Can't open %s\n", argv[1]);
		exit(EXIT_FAILURE);
	}
	if ((fp2 = fopen(argv[2], "r")) == NULL)
	{
		fprintf(stderr, "Can't open %s\n", argv[2]);
		exit(EXIT_FAILURE);
	}
	ch1 = getc(fp1);
	ch2 = getc(fp2);
	while (ch1 != EOF || ch2 != EOF)
	{
		while (ch1 != EOF && ch1 != '\n')
		{
			putchar(ch1);
			ch1 = getc(fp1);
		}
		if (ch1 != EOF)
		{
			putchar('\n');
			ch1 = getc(fp1);
		}
		while (ch2 != EOF && ch2 != '\n')
		{
			putchar(ch2);
			ch2 = getc(fp2);
		}
		if (ch2 != EOF)
		{
			putchar('\n');
			ch2 = getc(fp2);
		}
	}
	if (fclose(fp1) != 0 || fclose(fp2) != 0)
		fprintf(stderr, "Error closing file\n");

	return 0;
}
// 7a 方式二:提示用户输入文件名
#include <stdio.h>
#include <stdlib.h>
#define LEN 41
#define BUF 256   // 假设所有行都不超过256个字符

int main(void)
{
	FILE* fp1;
	FILE* fp2;
	char name1[LEN];
	char name2[LEN];
	char line[BUF];
	
	printf("Enter the first filename: ");
	scanf("%40s", name1);
	printf("Enter the second filename: ");
	scanf("%40s", name2);
	if ((fp1 = fopen(name1, "r")) == NULL)
	{
		fprintf(stderr, "Can't open %s\n", name1);
		exit(EXIT_FAILURE);
	}
	if ((fp2 = fopen(name2, "r")) == NULL)
	{
		fprintf(stderr, "Can't open %s\n", name2);
		exit(EXIT_FAILURE);
	}
	while (fgets(line, BUF, fp1) != NULL)
	{
		fputs(line, stdout);
		if (fgets(line, BUF, fp2) != NULL)
			fputs(line, stdout);
	}
	while (fgets(line, BUF, fp2) != NULL)    // 若第2个文件行数较多
		fputs(line, stdout);
	if (fclose(fp1) != 0 || fclose(fp2) != 0)
		fprintf(stderr, "Error closing file\n");

	return 0;
}
// 7b 方式一:使用命令行参数(方式二不单独列出)
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
	FILE* fp1;
	FILE* fp2;
	char ch1;
	char ch2;
	
	if (argc != 3)
	{
		fprintf(stderr, "Usage: %s filename1 filename2\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	if ((fp1 = fopen(argv[1], "r")) == NULL)
	{
		fprintf(stderr, "Can't open %s\n", argv[1]);
		exit(EXIT_FAILURE);
	}
	if ((fp2 = fopen(argv[2], "r")) == NULL)
	{
		fprintf(stderr, "Can't open %s\n", argv[2]);
		exit(EXIT_FAILURE);
	}
	ch1 = getc(fp1);
	ch2 = getc(fp2);
	while (ch1 != EOF || ch2 != EOF)
	{
		while (ch1 != EOF && ch1 != '\n')
		{
			putchar(ch1);
			ch1 = getc(fp1);
		}
		if (ch1 != EOF)
		{
			if (ch2 == EOF)
				putchar('\n');
			else
				putchar(' ');
			ch1 = getc(fp1);
		}
		while (ch2 != EOF && ch2 != '\n')
		{
			putchar(ch2);
			ch2 = getc(fp2);
		}
		if (ch2 != EOF)
		{
			putchar('\n');
			ch2 = getc(fp2);
		}
	}
	if (fclose(fp1) != 0 || fclose(fp2) != 0)
		fprintf(stderr, "Error closing file\n");

	return 0;
}

第8题

#include <stdio.h>
#include <stdlib.h>
int times_ch(char ch, FILE* fp);

int main(int argc, char* argv[])
{
	FILE* fp;
	char ch;
	int count;
	int i;

	if (argc < 2)
	{
		fprintf(stderr, "Usage: %s character (filename)\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	ch = argv[1][0];
	if (argc == 2)
	{
		puts("Enter text to analyze");
		puts("(press \"CTRL+Z\" at the beginning of a line to terminate):");
		count = times_ch(ch, stdin);
		printf("%c appears %d time(s) in the text.\n", ch, count);
	}
	else
	{
		for (i = 2; i < argc; i++)
		{
			if ((fp = fopen(argv[i], "r")) == NULL)
			{
				fprintf(stderr, "Can't open %s\n", argv[i]);
				continue;
			}
			count = times_ch(ch, fp);
			printf("%c appears %d time(s) in %s\n", ch, count, argv[i]);
			fclose(fp);
		}
	}

	return 0;
}

int times_ch(char ch, FILE* fp)
{
	int c;
	int ct = 0;

	while ((c = getc(fp)) != EOF)
		if (c == ch)
			ct++;

	return ct;
}

第9题

#include <stdio.h>
#include <stdlib.h>
#define MAX 47

int main(void)
{
	FILE* fp;
	char words[MAX];
	int wordct = 0;

	if ((fp = fopen("wordy", "a+")) == NULL)
	{
		fprintf(stderr, "Can't open \"wordy\" file.\n");
		exit(EXIT_FAILURE);
	}
	rewind(fp);
	while (fgets(words, MAX, fp) != NULL)
		wordct++;
	rewind(fp);

	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, "%3d: %s\n", ++wordct, words);

	puts("File contents:");
	rewind(fp);
	while (fgets(words, MAX, fp) != NULL)
		fputs(words, stdout);
	if (fclose(fp) != 0)
		fprintf(stderr, "Error closing file\n");

	return 0;
}

第10题

#include <stdio.h>
#include <stdlib.h>
#define LEN 41

int main(void)
{
	FILE* fp;
	char fname[LEN];
	int ch;
	long pos;
	long range;

	printf("Enter the filename: ");
	scanf("%40s", fname);
	if ((fp = fopen(fname, "rb")) == NULL)  // 必须以二进制模式打开文件
	{
		fprintf(stderr, "Can't open %s\n", fname);
		exit(EXIT_FAILURE);
	}
	printf("Enter the position you want to start reading from?\n");
	while (scanf("%d", &pos) == 1 && pos >= 0)
	{
		// 检查是否超出文件范围
		fseek(fp, 0L, SEEK_END);
		range = ftell(fp);
		if (pos >= range)
		{
			printf("Out of range, please enter again:\n");
			continue;
		}
		// 定位、输出
		fseek(fp, pos, SEEK_SET);
		while ((ch = getc(fp)) != '\n')
			putchar(ch);
		putchar('\n');
		printf("Next position:\n");
	}
	if (fclose(fp) != 0)
		fprintf(stderr, "Error closing file\n");
	printf("Bye.\n");

	return 0;
}

第11题

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 256

int main(int argc, char* argv[])
{
	FILE* fp;
	char line[SIZE];

	if (argc != 3)
	{
		fprintf(stderr, "Usage: %s string filename\n", argv[0]);
		exit(EXIT_FAILURE);
	}
	if ((fp = fopen(argv[2], "r")) == NULL)
	{
		fprintf(stderr, "Can't open %s\n", argv[2]);
		exit(EXIT_FAILURE);
	}
	while (fgets(line, SIZE, fp) != NULL)
	{
		if (strstr(line, argv[1]) != NULL)
			fputs(line, stdout);
	}	
	if (fclose(fp) != 0)
		fprintf(stderr, "Error closing file\n");

	return 0;
}

第12题

#include <stdio.h>
#include <stdlib.h>
#define ROWS 20
#define COLS 30
#define LEVELS 10
const char trans[LEVELS] = " .':~*=&%#";

int main(void)
{
	FILE* fp;
	int picIn[ROWS][COLS];
	char picOut[ROWS][COLS + 1];
	char fname[41];
	int i, j;

	printf("Enter the filename: ");
	scanf("%40s", fname);
	// 打开数据文件
	if ((fp = fopen(fname, "r")) == NULL)
	{
		fprintf(stderr, "Can't open %s\n", fname);
		exit(EXIT_FAILURE);
	}
	// 读取数据
	for (i = 0; i < ROWS; i++)
		for (j = 0; j < COLS; j++)
			fscanf(fp, "%d", &picIn[i][j]);
	if (ferror(fp))
	{
		fprintf(stderr, "Error getting data from file\n");
		exit(EXIT_FAILURE);
	}
	// 将数字转换成字符
	for (i = 0; i < ROWS; i++)
		for (j = 0; j < COLS; j++)
			picOut[i][j] = trans[picIn[i][j]];
	for (i = 0; i < ROWS; i++)
		picOut[i][COLS] = '\0';
	// 显示字符图片
	for (i = 0; i < ROWS; i++)
		puts(picOut[i]);
	// 将字符图片保存在原文件中,并关闭文件
	fclose(fp);
	if ((fp = fopen(fname, "w")) == NULL)
	{
		fprintf(stderr, "Can't open %s\n", fname);
		exit(EXIT_FAILURE);
	}
	for (i = 0; i < ROWS; i++)
		fprintf(fp, "%s\n", picOut[i]);
	fclose(fp);

	return 0;
}

第13题

// 本人IDE不支持变长数组,无法编译
#include <stdio.h>
#include <stdlib.h>
#define LEVELS 10
const char trans[LEVELS] = " .':~*=&%#";

int main(void)
{
	FILE* fp;
	int rows = 20;
	int cols = 30;
	int picIn[rows][cols];
	char picOut[rows][cols + 1];
	char fname[41];
	int i, j;

	printf("Enter the filename: ");
	scanf("%40s", fname);
	// 打开数据文件
	if ((fp = fopen(fname, "r")) == NULL)
	{
		fprintf(stderr, "Can't open %s\n", fname);
		exit(EXIT_FAILURE);
	}
	// 读取数据
	for (i = 0; i < rows; i++)
		for (j = 0; j < cols; j++)
			fscanf(fp, "%d", &picIn[i][j]);
	if (ferror(fp))
	{
		fprintf(stderr, "Error getting data from file\n");
		exit(EXIT_FAILURE);
	}
	// 将数字转换成字符
	for (i = 0; i < rows; i++)
		for (j = 0; j < cols; j++)
			picOut[i][j] = trans[picIn[i][j]];
	for (i = 0; i < rows; i++)
		picOut[i][cols] = '\0';
	// 显示字符图片
	for (i = 0; i < rows; i++)
		puts(picOut[i]);
	// 将字符图片保存在原文件中,并关闭文件
	fclose(fp);
	if ((fp = fopen(fname, "w")) == NULL)
	{
		fprintf(stderr, "Can't open %s\n", fname);
		exit(EXIT_FAILURE);
	}
	for (i = 0; i < rows; i++)
		fprintf(fp, "%s\n", picOut[i]);
	fclose(fp);

	return 0;
}

第14题

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define ROWS 20
#define COLS 30
#define LEVELS 10
const char trans[LEVELS] = " .':~*=&%#";
void eli_distortion(int data[][COLS], int row);

int main(void)
{
	FILE* fp;
	int picIn[ROWS][COLS];
	char picOut[ROWS][COLS + 1];
	char fname[41];
	int i, j;

	printf("Enter the filename: ");
	scanf("%40s", fname);
	// 打开数据文件
	if ((fp = fopen(fname, "r")) == NULL)
	{
		fprintf(stderr, "Can't open %s\n", fname);
		exit(EXIT_FAILURE);
	}
	// 读取数据
	for (i = 0; i < ROWS; i++)
		for (j = 0; j < COLS; j++)
			fscanf(fp, "%d", &picIn[i][j]);
	if (ferror(fp))
	{
		fprintf(stderr, "Error getting data from file\n");
		exit(EXIT_FAILURE);
	}
	// 消除失真
	eli_distortion(picIn, ROWS);
	// 将数字转换成字符
	for (i = 0; i < ROWS; i++)
		for (j = 0; j < COLS; j++)
			picOut[i][j] = trans[picIn[i][j]];
	for (i = 0; i < ROWS; i++)
		picOut[i][COLS] = '\0';
	// 显示字符图片
	for (i = 0; i < ROWS; i++)
		puts(picOut[i]);
	// 将字符图片保存在原文件中,并关闭文件
	fclose(fp);
	if ((fp = fopen(fname, "w")) == NULL)
	{
		fprintf(stderr, "Can't open %s\n", fname);
		exit(EXIT_FAILURE);
	}
	for (i = 0; i < ROWS; i++)
		fprintf(fp, "%s\n", picOut[i]);
	fclose(fp);

	return 0;
}

void eli_distortion(int data[][COLS], int row)
{
	int i, j;
	int up, down, left, right;
	int sum;
	int ct;

	for (i = 0; i < row; i++)
		for (j = 0; j < COLS; j++)
		{
			sum = ct = 0;
			up = down = left = right = 1;		
			if (i > 0)        // 上有相邻
			{
				up = abs(data[i][j] - data[i - 1][j]) > 1 ? 1 : 0;
				sum += data[i - 1][j];
				ct++;
			}
			if (i < row - 1)  // 下有相邻
			{
				down = abs(data[i][j] - data[i + 1][j]) > 1 ? 1 : 0;
				sum += data[i + 1][j];
				ct++;
			}
			if (j > 0)        // 左有相邻
			{
				left = abs(data[i][j] - data[i][j - 1]) > 1 ? 1 : 0;
				sum += data[i][j - 1];
				ct++;
			}
			if (j < COLS - 1) // 右有相邻
			{
				right = abs(data[i][j] - data[i][j + 1]) > 1 ? 1 : 0;
				sum += data[i][j + 1];
				ct++;
			}
			if (up && down && left && right)
				data[i][j] = (int)(1.0 * sum / ct + 0.5);  // 四舍五入为整数
		}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值