《C和指针》笔记

第一个程序是第一章中的例子,第一次使用vim和gcc,花了好长时间才调试好,写完后一直放着没有整理。这里把一些零碎的东西整理一下。

这个程序的目的是从标准输入读取文本并对其进行修改,然后把它显示到标准输出。首先读取一行串列标号,这些列标号成对出现,表示输入行的列范围。这串列标号以一个负值结尾。剩余的输入行被程序读入并打印,然后输入行被选中范围的字符串被提取出来并打印。注意,每行第1列的列标号为0:

下面是程序的执行示例:


最后一行是在命令行下输入的EOF,此时会退出程序。

下面是程序的代码:注释写的很详细了,就不解释了。

/*这个程序从标准输入中读取输入行并在标准输出中打印这些输出行,
 * 每个输入行的后面一行是该行内容的一部分。
 *
 * 输入的第一行是一串列标号,串的最后以一个负数结尾
 * 这些列标号成对出现,说明需要打印的输入行的列范围。
 * 例如:0 3 10 12 -1 表示第0列到第3列,第10列到第12列的内容将被打印*/

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

#define MAX_COLS 20  /*所能处理的最大列号*/
#define MAX_INPUT 1000 /*每个输入行的最大长度*/

int read_column_number(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];/*容纳输出行的数组*/

	/*读取该串列标号*/
	n_columns=read_column_number(columns,MAX_COLS);

	/*读取,处理,打印剩余的输入行*/
	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_number(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_INPUT-1)
			nchars=MAX_INPUT-output_col-1;

		/*复制相关数据*/
		strncpy(output+output_col,input+columns[col],nchars);
		output_col+=nchars;
	}
	output[output_col]='\0';
}
主要是一个标准库函数:gets,puts,scanf,getchar,strlen,strncpy的用法,这些函数可以参考c的文档说明。

这里我测试了一下gets函数,

#include <stdio.h>
#include <stdlib.h>
int main(){
	char input[20];
	while((gets(input)!=NULL)){
		int len=strlen(input);
		printf("len output:%d \n",len);
		for(int i=0;i<len;i++)
		{
			printf("%c\n",input[i]);
		}
		printf("20 output:\n");
		for(int i=0;i<20;i++){
			printf("%c,%d\n",input[i],input[i]);
		}
	}
}
输入abcde,下面是输出结果:可以发现输入abcde时,gets函数往数组input中依次存储了'a','b','c','d','e'和'\0'这几个字符,使用strlen(input)返回5就很好理解了。使用这个方法可以测试其它函数的一些细节问题。

下面是gets函数的功能说明:从stdin流中读取字符串,直至接受到换行符或EOF时停止,并将读取的结果存放在buffer指针所指向的字符数组中。换行符不作为读取串的内容,读取的换行符被转换为‘\0’空字符,并由此来结束字符串。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值