《C和指针》学习笔记1

近日得知《C和指针》这本书很经典,迫不及待的从网上购入一本,开始了漫长的啃书时光。作为刚刚走入C语言大门的菜鸟,这本书对我来说还是非常吃力,但我相信功夫不负有心人,坚持下去会有收获。为此决定把学习中碰到的问题整理下来,以供日后参考。

 

源代码:

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

#define MAX_COLS 20
#define MAX_INPUT 1000

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

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

	n_columns = readColumnNumbers(columns, MAX_COLS);

	while (gets_s(input)!=NULL)
	{
		printf("Qriginal input:%s\n",input);
		rearrange(output,input,n_columns,columns);
		printf("Rearrange line:%s\n",output);
	}

	system("pause");
	return EXIT_SUCCESS;
}

int readColumnNumbers(int columns[], int max)
{
	int num = 0;
	int ch;

	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;
}

void rearrange(char* output, char const* input, int n_columns, int const columns[])
{
	int col;
	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';
}

一.scanf()函数

代码1.1

while (num < max && scanf("%d", &columns[num]) == 1 && columns[num] >= 0)
{
	num += 1;
}

第一次看此代码我以为判断scanf输入的数等不等于1,程序还少打了一个&,但编译器没有报错。运行程序以后怎么输入也不好使,为此上网查询了scanf函数的文档,得知此函数是有返回值的函数。

scanf函数返回成功读入的数据项数,读入数据时遇到了“文件结束”则返回EOF。

代码1.2

int a,b,c,n;

printf("输入一个数:");
n = scanf("%d",&a);
printf("输入一个数的返回值是%d\n",n);

printf("输入三个数:");
n = scanf("%d%d%d", &a,&b,&c);
printf("输入三个数的返回值是%d\n", n);

printf("输入三个字母:");
n = scanf("%d%d%d", &a, &b, &c);
printf("输入三个数的返回值是%d\n", n);
printf("输入Ctrl+Z:");
n = scanf("%d", &a);
printf("输入Ctrl+Z的返回值是%d\n", n);

运行结果:


注:VS输入Ctrl+Z需要输入三次,VC++一次就可以

为此做了代码1.2的测试

a被成功读入,返回值为1,函数返回值为int型

a,b,c被成功读入,返回值为3;

a,b,c都未被成功读入,返回值为0;

如果遇到错误或遇到Ctrl+z 或者Ctrl+d,返回值为EOF。

补充:C语言中,EOF常被作为文件结束的标志。还有很多文件处理函数处错误后的返回值也是EOF,因此常被用来判断调用一个函数是否成功,在<stdio.h>中定义的。

#define EOF    (-1)

至此这个while循环条件能就弄明白了,读取的数为负数或等于EOF或长度大于数组循环结束,作用是输入正整数。

二.使用while ((ch = getchar()) != EOF && ch != '\n');消除非法输入

代码2.1

while ((ch = getchar()) != EOF && ch != '\n');

1.getchar()函数

百度百科介绍:getchar()是stdio.h中的库函数,它的作用是从stdin流中读入一个字符,也就是说,如果stdin有数据的话不用输入它就可以直接读取了,第一次调用getchar()时,确实需要人工的输入,但是如果你输了多个字符,以后的getchar()再执行时就会直接从缓冲区中读取了。

利用getchar函数的特点,就可以消除非法留下的字符,看以下例子:

代码2.1.1

char ch;
int a;

scanf("%d",&a);
printf("a=%d\n", a);

ch = getchar();
printf("%c\n",ch);

ch = getchar();
printf("%c\n", ch);

ch = getchar();
printf("%c\n", ch);

ch = getchar();
printf("%c\n", ch);

如果输入123QWE,则运行结果如下:

变量a被赋予了值123,字母QWE并没有被赋给变量a,而是留在了缓冲区。

使用getchar函数可以获取缓冲区中的字符。

第一次变量ch获取了字母Q

第二次变量ch获取了字母W

第三次变量ch获取了字母E

而第三次变量ch则获取了'\n'(换行符)。

补充:

getch()函数

getch与getchar基本功能相同,差别是getch直接从键盘获取键值,不等待用户按回车,只要用户按一个键,getch就立刻返回,getch返回值是用户输入的ASCⅡ码,出错返回-1。输入的字符不会回显在屏幕上,getch函数常用于程序调试中,在调试时,在关键位置显示有关的结果以待查看,然后用getch函数暂停程序运行,当按任意键后程序继续运行。getch()是非缓冲输入函数,就是不能用getch()来接受缓冲区已存在的字符。(getch函数不是标准C函数,使用时应使用conio.h头文件)

2.代码2.1的作用

当尚未达到文件的末尾或读取的字符并不是换行符,它将继续读取下一个字符,这条语句用来消除非法输入。

<!----未完待续---->

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值