书中第一章首先是一篇很有技巧性的c代码
/*
** 这个程序从标准输入中读取输入行并在标准输出中打印这些输入行
**每个输入行的后面一行是该行内容的一部分
**
**输入的第一行是一串列标号,串的最后以一个负数结尾
**这些列标号承兑出现,说明需要被打印的输入行的列范围
**例如,0 3 10 12 -1表示第0列到第3列,第10列到第12列的内容将被打印
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_CLOS 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[MAX_CLOS]);
int main(void)
{
int n_columns; /*进行处理的列标号*/
int columns[MAX_CLOS]; /*需要处理的列数*/
char input[MAX_INPUT]; /*需要容纳的输入的数组*/
char output[MAX_INPUT]; /*容纳输出行的数组*/
n_columns=read_column_numbers(columns,MAX_CLOS);
while(gets(input)!=NULL) /*如果读入不存在输入行则程序结束*/
{
printf("Original input :%s\n",input);
rearrange(output,input,n_columns,columns);
printf("Rearranged line :%s\n",output);
}
return EXIT_SUCCESS;
}
/*读取需要处理的列标号,如果超出规定范围不予理会*/
int read_column_numbers(int columns[],int max)
{
int num=0;
int ch;
while(num<max&&scanf("%d",&columns[num])==1&&columns[num]>0)
{
/*这个循环条件保证了读取的行号不会超过最大值,而且利用&&的短路特性,
也不会即使超过最大行号也不会被scanf读入,同时scanf保证了读入整型数据,
同时后面的条件输入的为正数*/
num+=1;
}
/*判断是否读入的数据是成对的*/
if(num%2!=0)
{
puts("Last column number is not paired.");
exit(EXIT_FAILURE);
}
while((ch=getchar())!=EOF&&ch!='\n'); /*用来处理包含最后那个负值的所有字符*/
return num;
}
/*处理输入行*/
void rearrange(char *output,char const*input,int n_columns,int const columns[MAX_CLOS])
{
int col; /*columns数组的下标*/
int output_col; /*输出行的列计数器*/
int len; /*输入行的长度*/
int nchars; /*成对处理的列之间的长度*/
len=strlen(input);
output_col=0;
for(col=0;col<n_columns;col+=2)
{
if(columns[col]>=len||output_col==MAX_INPUT-1) /*如果输入行的标号小于需要处理的列标号或者
输出数组已满结束任务*/
break;
nchars=columns[col+1]-columns[col]+1;
if(output_col+nchars>MAX_INPUT-1);
nchars=MAX_INPUT-output_col-1; /*如果输出行数据空间不够则只处理到能容纳到的数据*/
strncpy(output+output_col,input+columns[col],nchars);
output_col+=nchars;
}
output[output_col]='\0';
}
1.1.1 空白和注释
最开始一段就是注释,以/*
开始,以*/
,在c程序中,凡是可以插入空白的地方都可以插入注释。但是注释不能嵌套,也就是说第一个/*
与第一个*