C与指针读书笔记(1)

文章中的程序实现

/*
* 这个程序从标准输入中读取输入行并在标准输出中打印这些输入行
* 每个输入行的后面一行是该行的内容
* 
* 输入的第一行是一串列标号,串最后以一个负数结尾
* 这些列标号成对出现的时,说明需要打印的输入行的列的范围
* 例如;0 3 10 12 -1 表明第0列到第3列,第10列到第12列的内容将被打印
*/
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_COLS 20     /*所能处理的最大的列号*/
#define MAX_INPUT 1000  /*每行的最大长度*/

//以上是整个工程的预处理指令,预处理指令读入源代码,根据预处理指令对其进行修改,然后把修改过的源代码递交给编译器

int read_column_numbers(int columns[], int max);
void rearrange(char* output, char const* input, int n_columns, int const columns[] );

int main() 
{
	int n_columns;
	int columns[MAX_COLS];
	char input[MAX_INPUT];
	char output[MAX_INPUT];

	/*
	* read the line number
	*/
	n_columns = read_column_numbers(columns, MAX_COLS);//这句话可以用下面这个进行表述:在C语言中所有的参数传递规则的是:所有传递给函数的参数都是按值传递的。

	/*
	* 读取、处理和打印剩余的输入行
	*/
	while (gets_s( input ) != NULL )
	{
		printf("Original input :%s\n", input);
		rearrange(output,input,n_columns,columns);
		printf("Rearrange line: %s\n",output);
	}

	return EXIT_SUCCESS;
}

/*
* 读取列表号,如果超出规定范围则不予理会
*/
int read_column_numbers(int columns[], int max)
{
	int num = 0;
	int ch;
	/*
	* 取得列表号,如果索取的数小于0,则停止。
	*/
	while (num < max && (scanf("%d",&columns[num]) == 1) && columns[num] >= 0 )
		num += 1;
	/*
	* 确认已经读取的标号为偶个,因为他们是以对的形式出现的
	*/
	if (num % 2 != 0)
	{
		puts("Last column number is not paired.");
		exit(EXIT_FAILURE);
	}

	/*
	* 丢弃该行中包含最后一个数字的那部分内容。
	*/
	while ((ch = getchar()) != EOF && ch != '\n')
		;

	return num;
}

/*
* 处理输入行,将指定列的数符链接在一起,输出行医nul结尾
*/
void rearrange(char* output, char const* input, int n_columns, int const columns[])
{
	int col;        //columns数组的下标
	int output_col; //输出列计算器
	int len;        //输入行的长度

	len = strlen(input);
	output_col = 0;

	/*
	* 处理每对列标号
	*/
	for (col = 0; col < n_columns; col += 2)
	{
		int nchars = columns[col + 1] - columns[col] + 1;

		//如果输入行结束或输出行数组已满,就结束任务。
		if (columns[col] >= len || output_col == MAX_INPUT - 1 )
		{
			break;
		}

		//如果输出的数据空间不够,只复制可以容纳的数据
		if (output_col + nchars > MAX_COLS - 1)
			nchars = MAX_INPUT - output_col - 1;

		//复制相关数据
		strncpy(output + output_col, input + columns[col], nchars);
		output_col += nchars;
	}
	output[output_col] = '\0';
}

课后编程练习第2题

/*

  • 通过从输入中逐字符进行读取而不是逐行进行读取,可以避免行进行长度限制。
    */
#include <stdio.h>
#include<stdlib.h>

int main()
{
	int ch;
	int line = 0;
	int at_beginning = 1;

	//读取字符并逐个处理他们
	while ((ch = getchar()) != EOF)
	{
		//如果位于一行的起始位置,就打印行号
		if (at_beginning == 1)
		{
			at_beginning = 0;
			line += 1;
			printf("%d", line);
		}

		//打印字符,并对行尾进行检查
		putchar( ch );
		if (ch == '\n')
			at_beginning = 1;
	}
	return EXIT_SUCCESS;
}

对于以上程序中,有一个问题是不知道EOF时什么意思,在C语言中EOF代表着End Of File,在操作系统中表示资料源无更多的资料可读取。资料源通常称为档案或串流。在C语言中,或更精确地说成C标准函式库中表示文件结束符(end of file)。在while循环中以EOF作为文件结束标志,这种以EOF作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的ASCII代码值的形式存放。我们知道,ASCII代码值的范围是0~255,不可能出现-1,因此可以用EOF作为文件结束标志。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值