C语言学习记录(1)ASCII码排序

C语言学习记录

前言

一直自己没有学习做笔记的习惯,所以为了加强自己对知识的深入理解,决定将学习笔记写下来,希望向各位大牛们学习交流!

不当之处请斧正!在此感谢!这边就先从学习C语言写起,自己本身对程序语言方面不擅长,所以决定对此从基础开始学习,

大牛们对此文可以忽略!

C语言作业

在写c语言作业的时候有这样一道题:

ASCII码排序

题目描述
输入三个字符后,按各字符的ASCII码从小到大的顺序输出这三个字符。
输入描述
输入数据有多组,每组占一行,有三个字符组成,之间无空格。
输出描述
对于每组输入数据,输出一行,字符中间用一个空格分开。
输入样例
qwe
asd
zxc
输出样例
e q w
a d s
c x z

于是我选择最笨的方法:

#include <stdio.h>

int main() {
	char a,b,c;
	while(scanf("%c%c%c",&a,&b,&c)!=EOF)
	{

		if(a>b)
		{
			if(b>c)
			{
				printf("%c %c %c\n",c,b,a);
			}
			else
			{
				if(a>c)
				{
				printf("%c %c %c\n",b,c,a);
				}
				else
				{
				printf("%c %c %c\n",b,a,c);
				}
			}

		}
		else
		{
			if(b<c)
			{
				printf("%c %c %c\n",a,b,c);
			}
			else
			{
				if(a>c)
				{
				printf("%c %c %c\n",c,a,b);
				}
				else
				{
				printf("%c %c %c\n",a,c,b);
				}
			}

		}
	}
    return 0;
}

然后我发现第一轮输入输出没问题,后面输入输出的时候scanf就会把回车输进去,上BAIDU查了下,是因为键盘缓冲区的清除问题。于是我加了fflush(stdin);

#include <stdio.h>

int main() {
	char a,b,c;
	while(scanf("%c%c%c",&a,&b,&c)!=EOF)
	{

		if(a>b)
		{
			if(b>c)
			{
				printf("%c %c %c\n",c,b,a);
			}
			else
			{
				if(a>c)
				{
				printf("%c %c %c\n",b,c,a);
				}
				else
				{
				printf("%c %c %c\n",b,a,c);
				}
			}

		}
		else
		{
			if(b<c)
			{
				printf("%c %c %c\n",a,b,c);
			}
			else
			{
				if(a>c)
				{
				printf("%c %c %c\n",c,a,b);
				}
				else
				{
				printf("%c %c %c\n",a,c,b);
				}
			}

		}
		fflush(stdin)}
    return 0;
}

终于没问题了,输入ok,输出no problem。
但是放到作业里提交无论如何都是答案错误,改什么都没用,叫了舍友讨论逻辑啊,代码啊,无解。C语言学习记录(1)ASCII码排序_第1张图片

于是上床休息,第二天早上继续分析,灵光一闪,会不会是我加的fflush(stdin); 的问题于是我又BAIDU了下,确实是:

C和C++的标准里从来没有定义过 fflush(stdin)。
也许有人会说:“可是我用 fflush(stdin) 解决了这个问题,你怎么能说是错的呢?”
的确,某些编译器(如VC6)支持用 fflush(stdin) 来清空输入缓冲,
但是并非所有编译器都要支持这个功能(linux 下的 gcc 就不支持),
因为标准中根本没有定义 fflush(stdin)。

MSDN 文档里 也清楚地写着
fflush on input stream is an extension to the C standard(fflush 操作输入流是对 C 标准的扩充)。
当然,如果你毫不在乎程序的移植性,用 fflush(stdin) 也没什么大问题。
以下是 C99 对 fflush 函数的定义:
int fflush(FILE *stream);
如果 stream 指向输出流或者更新流(update stream),
并且这个更新流最近执行的操作不是输入,
那么 fflush 函数将把这个流中任何待写数据传送至宿主环境(host environment)写入文件。
否则,它的行为是未定义的。

原文如下:
int fflush(FILE *stream);
If stream points to an output stream or an update stream in which
the most recent operation was not input, the fflush function causes
any unwritten data for that stream to be delivered to the host environment
to be written to the file; otherwise, the behavior is undefined.

其中,宿主环境可以理解为操作系统或内核等。
由此可知,如果 stream 指向输入流(如 stdin),那么 fflush 函数的行为是不确定的。故而使用 fflush(stdin) 是不正确的,至少是移植性不好的。

办法是

while ( (c = getchar()) != '\n' && c != EOF ) ;   
 /*可直接将这句代码当成fflush(stdio)的替代,直接运行可清除输入缓存流*/
  /* 使用 scanf("%*[^\n]"); 也可以清空输入流, */
  /* 不过会残留 \n 字符。                          */

替换之后

#include <stdio.h>

int main() {
  char a,b,c;
  while(scanf("%c%c%c",&a,&b,&c)!=EOF)
  {

  	if(a>b)
  	{
  		if(b>c)
  		{
  			printf("%c %c %c\n",c,b,a);
  		}
  		else
  		{
  			if(a>c)
  			{
  			printf("%c %c %c\n",b,c,a);
  			}
  			else
  			{
  			printf("%c %c %c\n",b,a,c);
  			}
  		}

  	}
  	else
  	{
  		if(b<c)
  		{
  			printf("%c %c %c\n",a,b,c);
  		}
  		else
  		{
  			if(a>c)
  			{
  			printf("%c %c %c\n",c,a,b);
  			}
  			else
  			{
  			printf("%c %c %c\n",a,c,b);
  			}
  		}

  	}
  	while ( (c = getchar()) != '\n' && c != EOF ) ;  
  }
  return 0;
}

当当当当

正确结果

参考资料:
[1]: C语言scanf函数详细解释 https://blog.csdn.net/21aspnet/article/details/174326
[2]:开源中国 https://my.oschina.net/deanzhao/blog/79790

你可能感兴趣的:(C语言)